mirror of
https://github.com/csharpee/Map-Projections.git
synced 2025-12-21 00:00:16 -05:00
Exacto
I got the equations perfect. The Dymaxion projection is complete. And by far my slowest projection.
This commit is contained in:
parent
2687fea6a4
commit
9dfc72f4b8
@ -107,7 +107,7 @@ public abstract class MapApplication extends Application {
|
|||||||
private static final KeyCombination CTRL_ENTER = new KeyCodeCombination(KeyCode.ENTER, KeyCodeCombination.CONTROL_DOWN);
|
private static final KeyCombination CTRL_ENTER = new KeyCodeCombination(KeyCode.ENTER, KeyCodeCombination.CONTROL_DOWN);
|
||||||
|
|
||||||
|
|
||||||
public static final Projection[] FEATURED_PROJECTIONS = { Polyhedral.DYMAXION, Cylindrical.MERCATOR,
|
public static final Projection[] FEATURED_PROJECTIONS = { Cylindrical.MERCATOR,
|
||||||
Cylindrical.EQUIRECTANGULAR, Cylindrical.EQUAL_AREA, Cylindrical.GALL_STEREOGRAPHIC,
|
Cylindrical.EQUIRECTANGULAR, Cylindrical.EQUAL_AREA, Cylindrical.GALL_STEREOGRAPHIC,
|
||||||
Azimuthal.STEREOGRAPHIC, Azimuthal.POLAR, Azimuthal.EQUAL_AREA, Azimuthal.GNOMONIC,
|
Azimuthal.STEREOGRAPHIC, Azimuthal.POLAR, Azimuthal.EQUAL_AREA, Azimuthal.GNOMONIC,
|
||||||
Azimuthal.PERSPECTIVE, Conic.LAMBERT, Conic.EQUIDISTANT, Conic.ALBERS,
|
Azimuthal.PERSPECTIVE, Conic.LAMBERT, Conic.EQUIDISTANT, Conic.ALBERS,
|
||||||
@ -126,8 +126,9 @@ public abstract class MapApplication extends Application {
|
|||||||
{ Azimuthal.EQUAL_AREA, Azimuthal.POLAR, Azimuthal.GNOMONIC, Azimuthal.ORTHOGRAPHIC,
|
{ Azimuthal.EQUAL_AREA, Azimuthal.POLAR, Azimuthal.GNOMONIC, Azimuthal.ORTHOGRAPHIC,
|
||||||
Azimuthal.PERSPECTIVE, Azimuthal.STEREOGRAPHIC },
|
Azimuthal.PERSPECTIVE, Azimuthal.STEREOGRAPHIC },
|
||||||
{ Conic.ALBERS, Conic.LAMBERT, Conic.EQUIDISTANT },
|
{ Conic.ALBERS, Conic.LAMBERT, Conic.EQUIDISTANT },
|
||||||
{ Polyhedral.AUTHAGRAPH, CahillKeyes.M_MAP, Polyhedral.LEE_TETRAHEDRAL_RECTANGULAR,
|
{ Polyhedral.AUTHAGRAPH, CahillKeyes.M_MAP, Polyhedral.DYMAXION,
|
||||||
Polyhedral.LEE_TETRAHEDRAL_TRIANGULAR, Waterman.BUTTERFLY },
|
Polyhedral.LEE_TETRAHEDRAL_RECTANGULAR, Polyhedral.LEE_TETRAHEDRAL_TRIANGULAR,
|
||||||
|
Waterman.BUTTERFLY },
|
||||||
{ Pseudocylindrical.ECKERT_IV, Pseudocylindrical.KAVRAYSKIY_VII,
|
{ Pseudocylindrical.ECKERT_IV, Pseudocylindrical.KAVRAYSKIY_VII,
|
||||||
Pseudocylindrical.MOLLWEIDE, Arbitrary.NATURAL_EARTH, Arbitrary.ROBINSON,
|
Pseudocylindrical.MOLLWEIDE, Arbitrary.NATURAL_EARTH, Arbitrary.ROBINSON,
|
||||||
Pseudocylindrical.SINUSOIDAL, Tobler.TOBLER },
|
Pseudocylindrical.SINUSOIDAL, Tobler.TOBLER },
|
||||||
|
|||||||
@ -233,13 +233,16 @@ public class Polyhedral {
|
|||||||
|
|
||||||
public static final Projection DYMAXION =
|
public static final Projection DYMAXION =
|
||||||
new PolyhedralProjection(
|
new PolyhedralProjection(
|
||||||
"Dymaxion", "A polyhedral projection that slices up the oceans as much as possible without slicing up any continents.",
|
"Dymaxion", "A polyhedral projection that slices up the oceans as much as possible without slicing up any landmasses.",
|
||||||
0b1110, Configuration.DYMAXION, Property.COMPROMISE) {
|
0b1110, Configuration.DYMAXION, Property.COMPROMISE) {
|
||||||
|
|
||||||
private final double[] POLE = {0.040158, -0.091549,-2.015269}; //I derived these numbers from [Robert Gray](http://www.rwgrayprojects.com/rbfnotes/maps/graymap4.html)
|
private final double[] POLE = {0.040158, -0.091549,-2.015269}; //I derived these numbers from [Robert Gray](http://www.rwgrayprojects.com/rbfnotes/maps/graymap4.html)
|
||||||
private final double X_0 = 0.75;
|
private final double X_0 = 0.75;
|
||||||
private final double Y_0 = -Math.sqrt(3)/4;
|
private final double Y_0 = -Math.sqrt(3)/4;
|
||||||
|
|
||||||
|
private final double sin36 = Math.sqrt(10-2*Math.sqrt(5))/4;
|
||||||
|
private final double cos36 = (1+Math.sqrt(5))/4;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double[] project(double lat, double lon) { //apply a pole shift and Cartesian shift to Dymaxion
|
public double[] project(double lat, double lon) { //apply a pole shift and Cartesian shift to Dymaxion
|
||||||
double[] coords = obliquifySphc(lat, lon, POLE);
|
double[] coords = obliquifySphc(lat, lon, POLE);
|
||||||
@ -255,12 +258,26 @@ public class Polyhedral {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public double[] faceProject(double lat, double lon) {
|
public double[] faceProject(double lat, double lon) {
|
||||||
return new double[] {(Math.PI/2-lat)/1.1, lon*5/6};
|
if (Math.abs(lon) > Math.PI/5) throw new IllegalArgumentException("That's not possible!");
|
||||||
|
double xG = Math.cos(lon)/Math.tan(lat)/cos36; //normalised gnomonic coordinates
|
||||||
|
double yG = Math.sin(lon)/Math.tan(lat)/sin36;
|
||||||
|
double a = Math.asin((xG+yG)/(2*Math.sqrt(1+xG*xG))) + Math.atan(xG); //angular distance up each side of the triangle
|
||||||
|
double b = Math.asin((xG-yG)/(2*Math.sqrt(1+xG*xG))) + Math.atan(xG);
|
||||||
|
double x = (a + b)/(2*Math.sqrt(3)); //final cartesian coordinates in radians
|
||||||
|
double y = (a - b)/2;
|
||||||
|
return new double[] {Math.hypot(x,y)/Math.atan(2), Math.atan2(y,x)}; //scale to fit to layout, where side length is 1
|
||||||
}
|
}
|
||||||
|
|
||||||
public double[] faceInverse(double r, double th) {
|
public double[] faceInverse(double r, double th) {
|
||||||
if (r > Math.sqrt(1/3.)) return null;
|
if (Math.abs(th) > Math.PI/6) throw new IllegalArgumentException("Wait, what?");
|
||||||
return new double[] {Math.PI/2-r*1.1, th*6/5};
|
double x = r*Math.cos(th)*Math.atan(2); //cartesian coordinates in radians
|
||||||
|
double y = r*Math.sin(th)*Math.atan(2);
|
||||||
|
double a = Math.sqrt(3)*x + y; //angular distance up each side of the triangle
|
||||||
|
double b = Math.sqrt(3)*x - y;
|
||||||
|
double xG = cos36*(Math.sin(a) + Math.sin(b))/(1 + Math.cos(a) + Math.cos(b)); //unnormalised gnomonic coordinates
|
||||||
|
double yG = sin36*
|
||||||
|
(Math.sin(a) - Math.sin(b) + 2*Math.sin(a-b))/(1 + Math.cos(a) + Math.cos(b));
|
||||||
|
return new double[] {Math.atan(1/Math.hypot(xG, yG)), Math.atan2(yG, xG)}; //inverse gnomonic projection
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -311,10 +328,13 @@ public class Polyhedral {
|
|||||||
double[] centrum = null;
|
double[] centrum = null;
|
||||||
for (double[] testCentrum: configuration.centrumSet) { //iterate through the centrums to see which goes here
|
for (double[] testCentrum: configuration.centrumSet) { //iterate through the centrums to see which goes here
|
||||||
final double[] relCoords = obliquifySphc(lat, lon, testCentrum);
|
final double[] relCoords = obliquifySphc(lat, lon, testCentrum);
|
||||||
if (testCentrum.length > 6) //if the centrum is long, then it contains longitude bounds
|
if (testCentrum.length > 6) { //if the centrum is long, then it contains longitude bounds
|
||||||
if (relCoords[1] < testCentrum[6]*Math.PI/numSym ||
|
double minL = testCentrum[6]*Math.PI/numSym;
|
||||||
relCoords[1] > testCentrum[7]*Math.PI/numSym)
|
double maxL = testCentrum[7]*Math.PI/numSym;
|
||||||
|
relCoords[1] = Math2.floorMod(relCoords[1]-minL, 2*Math.PI) + minL;
|
||||||
|
if (relCoords[1] < minL || relCoords[1] > maxL)
|
||||||
continue; //ignore any longitudes not in the bounds described in [6:7]
|
continue; //ignore any longitudes not in the bounds described in [6:7]
|
||||||
|
}
|
||||||
|
|
||||||
if (relCoords[0] > latR) { //pick the centrum that maxes out latitude
|
if (relCoords[0] > latR) { //pick the centrum that maxes out latitude
|
||||||
latR = relCoords[0];
|
latR = relCoords[0];
|
||||||
@ -444,7 +464,7 @@ public class Polyhedral {
|
|||||||
{ ATAN_ONE_HLF, 0.0, 0.0, -Math.PI/2, 0.0, Math.sqrt(3)/2,-3,5 }, //Caribbean
|
{ ATAN_ONE_HLF, 0.0, 0.0, -Math.PI/2, 0.0, Math.sqrt(3)/2,-3,5 }, //Caribbean
|
||||||
{ ATAN_ONE_HLF, 0.0, -4*Math.PI/5,-5*Math.PI/6,-0.5, Math.sqrt(3), -1,1 }, //North Atlantic O.
|
{ ATAN_ONE_HLF, 0.0, -4*Math.PI/5,-5*Math.PI/6,-0.5, Math.sqrt(3), -1,1 }, //North Atlantic O.
|
||||||
{ ATAN_ONE_HLF, 2*Math.PI/5, 0.0, -Math.PI/2, 1.0, Math.sqrt(3)/2,-5,5 }, //Patagonia
|
{ ATAN_ONE_HLF, 2*Math.PI/5, 0.0, -Math.PI/2, 1.0, Math.sqrt(3)/2,-5,5 }, //Patagonia
|
||||||
{ ATAN_ONE_HLF, 4*Math.PI/5, 0.0, -Math.PI/2, 2.0, Math.sqrt(3)/2,-5,0 }, //East Antarctica
|
{ ATAN_ONE_HLF, 4*Math.PI/5,-2*Math.PI/5,-5*Math.PI/6, 2.0, Math.sqrt(3)/2,-3,2 }, //East Antarctica
|
||||||
{ ATAN_ONE_HLF, 4*Math.PI/5, 0.0, -Math.PI/6, -3.5, 0.0, 0,1 }, //South Indian O.
|
{ ATAN_ONE_HLF, 4*Math.PI/5, 0.0, -Math.PI/6, -3.5, 0.0, 0,1 }, //South Indian O.
|
||||||
{ ATAN_ONE_HLF, 4*Math.PI/5, 2*Math.PI/5,-Math.PI/6, -3.0, Math.sqrt(3)/2,-1,1 }, //North Indian O.
|
{ ATAN_ONE_HLF, 4*Math.PI/5, 2*Math.PI/5,-Math.PI/6, -3.0, Math.sqrt(3)/2,-1,1 }, //North Indian O.
|
||||||
{ ATAN_ONE_HLF, 4*Math.PI/5, 4*Math.PI/5,-Math.PI/6, -2.5, Math.sqrt(3), -1,1 }, //South Africa
|
{ ATAN_ONE_HLF, 4*Math.PI/5, 4*Math.PI/5,-Math.PI/6, -2.5, Math.sqrt(3), -1,1 }, //South Africa
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user