public void prepareForProjection(SphericalMaxProjection smp, int width) {

    double globeRadius = findRadiusForWidth(width, 0, 1000f);
    projection.setEllipsoid(new Ellipsoid("", globeRadius, globeRadius, 0.0D, ""));
    projection.initialize();

    if (!projection.hasInverse()) throw new RuntimeException("Inverse mapping missing");

    minx = Integer.MAX_VALUE;
    maxx = -minx;
    miny = minx;
    maxy = -minx;

    double dlon = projection.getMaxLongitude() - projection.getMinLongitude();
    double dlat = projection.getMaxLatitude() - projection.getMinLatitude();

    Point2D.Double tmpin = new Point2D.Double();
    Point2D.Double tmpout = new Point2D.Double();
    for (int lo = 0; lo <= 100; lo++) {
      for (int la = 0; la <= 100; la++) {
        tmpin.x = (lo - 50) * dlon / 100;
        tmpin.y = (la - 50) * dlat / 100;
        tmpin.x = (lo - 50) * dlon / 100;
        tmpin.y = (la - 50) * dlat / 100;
        projection.transformRadians(tmpin, tmpout);
        if (tmpout.x < minx) minx = (int) tmpout.x;
        if (tmpout.y < miny) miny = (int) tmpout.y;
        if (tmpout.x > maxx) maxx = (int) tmpout.x;
        if (tmpout.y > maxy) maxy = (int) tmpout.y;
      }
    }

    this.w = maxx - minx + 1;
    this.h = maxy - miny + 1;

    vIndices = new int[w * h][3];
    vertexWeights = new float[w * h][3];
    Point3f p = new Point3f();
    Point3f[] vertices = smp.getSphere().getVertices();
    int index = 0;
    for (int y = maxy; y >= miny; y--) {
      for (int x = minx; x <= maxx; x++) {
        Point2D.Double in = new Point2D.Double(x, y);
        Point2D.Double out = new Point2D.Double();
        out = projection.inverseTransformRadians(in, out);

        double lon = out.x;
        double lat = out.y;

        if (lat >= projection.getMaxLatitude()
            || lat <= projection.getMinLatitude()
            || lon >= projection.getMaxLongitude()
            || lon <= projection.getMinLongitude()) {
          index++;
          continue;
        }

        double sLon = (float) Math.sin(lon);
        double cLon = (float) Math.cos(lon);
        double sLat = (float) Math.sin(lat);
        double cLat = (float) Math.cos(lat);

        smp.getPoint(sLon, cLon, sLat, cLat, p);

        smp.getThreeNearestVertexIndices(p, vIndices[index]);

        // interpolate according to distance
        float d0 = 1 / p.distance(vertices[vIndices[index][0]]);
        float d1 = 1 / p.distance(vertices[vIndices[index][1]]);
        float d2 = 1 / p.distance(vertices[vIndices[index][2]]);
        float sum = d0 + d1 + d2;
        vertexWeights[index][0] = d0 / sum;
        vertexWeights[index][1] = d1 / sum;
        vertexWeights[index][2] = d2 / sum;

        index++;
      }
    }
  }