diff --git a/.idea/ant.xml b/.idea/ant.xml new file mode 100644 index 0000000..a2a4769 --- /dev/null +++ b/.idea/ant.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/MapAnalyzer.jar b/MapAnalyzer.jar index 23b9ca7..5228aec 100644 Binary files a/MapAnalyzer.jar and b/MapAnalyzer.jar differ diff --git a/MapDesignerRaster.jar b/MapDesignerRaster.jar index 1644ff1..458923f 100644 Binary files a/MapDesignerRaster.jar and b/MapDesignerRaster.jar differ diff --git a/MapDesignerVector.jar b/MapDesignerVector.jar index 198cbd3..1b20c1b 100644 Binary files a/MapDesignerVector.jar and b/MapDesignerVector.jar differ diff --git a/src/apps/MapApplication.java b/src/apps/MapApplication.java index a2a8ae1..5fe6450 100644 --- a/src/apps/MapApplication.java +++ b/src/apps/MapApplication.java @@ -139,8 +139,9 @@ public abstract class MapApplication extends Application { { Conic.ALBERS, Misc.BRAUN_CONIC, Conic.LAMBERT, Conic.EQUIDISTANT }, { Polyhedral.AUTHAGRAPH, Polyhedral.LEE_TETRAHEDRAL_RECTANGULAR, Polyhedral.LEE_TETRAHEDRAL_TRIANGULAR, Polyhedral.VAN_LEEUWEN }, - { Octohedral.CAHILL_CONCIALDI, Octohedral.CONFORMAL_CAHILL, Octohedral.CAHILL_KEYES, - Octohedral.KEYES_BASIC_M, Polyhedral.DYMAXION, Octohedral.WATERMAN }, + { Octohedral.CONFORMAL_CAHILL, Octohedral.CAHILL_CONCIALDI, Octohedral.KEYES_STANDARD, + Octohedral.KEYES_BASIC_M, Octohedral.KEYES_OCTANT, Polyhedral.DYMAXION, + Octohedral.WATERMAN }, { Pseudocylindrical.ECKERT_IV, EqualEarth.EQUAL_EARTH, Pseudocylindrical.HOMOLOSINE_INTERRUPTED, Pseudocylindrical.HOMOLOSINE, Pseudocylindrical.KAVRAYSKIY_VII, Pseudocylindrical.MOLLWEIDE, diff --git a/src/apps/MapExplainer.java b/src/apps/MapExplainer.java index e362a11..ab1124c 100644 --- a/src/apps/MapExplainer.java +++ b/src/apps/MapExplainer.java @@ -67,15 +67,13 @@ public class MapExplainer extends Application { Pseudocylindrical.MOLLWEIDE, Tobler.TOBLER, Lenticular.AITOFF, Lenticular.VAN_DER_GRINTEN, ArbitraryPseudocylindrical.ROBINSON, WinkelTripel.WINKEL_TRIPEL, Polyhedral.AUTHAGRAPH, - Polyhedral.LEE_TETRAHEDRAL_RECTANGULAR, Octohedral.CAHILL_KEYES, + Polyhedral.LEE_TETRAHEDRAL_RECTANGULAR, Octohedral.KEYES_STANDARD, Octohedral.CAHILL_CONCIALDI, Misc.PEIRCE_QUINCUNCIAL.transverse(), Snyder.GS50, Misc.TWO_POINT_EQUIDISTANT, Misc.HAMMER_RETROAZIMUTHAL, Misc.FLAT_EARTH }, { Meshed.DANSEIJI_N, Meshed.DANSEIJI_IV, Meshed.DANSEIJI_V, Polyhedral.TETRAGRAPH, Polyhedral.AUTHAPOWER, Polyhedral.ACTUAUTHAGRAPH } }; - - private PixelMap inputSkew, inputPole, inputNone, inputEast, inputWest; - - + + public static void main(String[] args) { launch(args); } @@ -83,6 +81,11 @@ public class MapExplainer extends Application { public void start(Stage stage) throws Exception { new File("images").mkdirs(); + PixelMap inputSkew; + PixelMap inputNone; + PixelMap inputEast; + PixelMap inputPole; + PixelMap inputWest; try { inputSkew = new PixelMap(new File("input/Advanced/Tissot Oblique.jpg")); inputPole = new PixelMap(new File("input/Advanced/Tissot Standard.jpg")); @@ -106,7 +109,7 @@ public class MapExplainer extends Application { PixelMap input = inputSkew; if (!proj.hasAspect() || proj == Polyhedral.AUTHAGRAPH) input = inputPole; - if (proj == Octohedral.CAHILL_KEYES) //some projections only look good in standard aspect + if (proj == Octohedral.KEYES_STANDARD) //some projections only look good in standard aspect input = inputWest; if (proj == Octohedral.CAHILL_CONCIALDI) input = inputEast; diff --git a/src/apps/MapPlotter.java b/src/apps/MapPlotter.java index e0fef23..6947839 100644 --- a/src/apps/MapPlotter.java +++ b/src/apps/MapPlotter.java @@ -84,7 +84,7 @@ public class MapPlotter extends Application { Meshed.DANSEIJI_II, Gyorffy.E, Gyorffy.F }; private static final Projection[] TETRAHEDRAL = { Polyhedral.LEE_TETRAHEDRAL_RECTANGULAR, Polyhedral.AUTHAGRAPH, Polyhedral.VAN_LEEUWEN }; - private static final Projection[] CHEATY = { Pseudocylindrical.LEMONS, Octohedral.CAHILL_KEYES, + private static final Projection[] CHEATY = { Pseudocylindrical.LEMONS, Octohedral.KEYES_STANDARD, Polyhedral.DYMAXION, Octohedral.CAHILL_CONCIALDI, Meshed.DANSEIJI_IV, Pseudocylindrical.HOMOLOSINE_INTERRUPTED }; private static final Projection[] OTHER = { Misc.PEIRCE_QUINCUNCIAL }; diff --git a/src/apps/MapProducer.java b/src/apps/MapProducer.java index b72ca5f..4f4e429 100644 --- a/src/apps/MapProducer.java +++ b/src/apps/MapProducer.java @@ -74,7 +74,7 @@ public class MapProducer extends Application { Polyhedral.DYMAXION, Misc.HAMMER_RETROAZIMUTHAL, Snyder.GS50, Azimuthal.STEREOGRAPHIC.withAspect("Oblique Stereographic", .5, 2.5, -2.5), Cylindrical.MERCATOR.withAspect("Oblique Mercator", .5, 2.5, 2.5), Misc.BONNE, - Misc.BRAUN_CONIC, Octohedral.CAHILL_CONCIALDI, Octohedral.CAHILL_KEYES, + Misc.BRAUN_CONIC, Octohedral.CAHILL_CONCIALDI, Octohedral.KEYES_STANDARD, Lenticular.EISENLOHR, Gyorffy.E, Lenticular.LAGRANGE, Lenticular.POLYCONIC, Polyhedral.VAN_LEEUWEN, Pseudocylindrical.WAGNER_II, Pseudocylindrical.WAGNER_V, Lenticular.WAGNER_VIII, Pseudocylindrical.HOMOLOSINE_INTERRUPTED }, diff --git a/src/maps/CahillKeyes.java b/src/maps/CahillKeyes.java index a4812d0..cbb1d39 100644 --- a/src/maps/CahillKeyes.java +++ b/src/maps/CahillKeyes.java @@ -56,9 +56,12 @@ public class CahillKeyes { private static final double yC = 1609.0110; //the y coordinate of the centre of arc CDV private static final double TOLERANCE = 5; //this is a reasonable tolerance when you recall that we're operating on the order of 10,000 units - - - public static final double[] faceProjectD(double latD, double lonD) { //convert adjusted lat and lon in degrees to Mary Jo's coordinates + + + /** + * convert adjusted lat and lon in degrees to Mary Jo's coordinates + */ + public static final double[] faceProjectD(double latD, double lonD) { final double[][] mer = meridian(lonD); if (latD >= 75) { //zone c (frigid zone) return new double[] { lMA + 104*(90-latD)*Math2.cosd(lonD), diff --git a/src/maps/Octohedral.java b/src/maps/Octohedral.java index b259a2d..a2e2f40 100644 --- a/src/maps/Octohedral.java +++ b/src/maps/Octohedral.java @@ -51,7 +51,7 @@ public class Octohedral { public static final Projection KEYES_BUTTERFLY = new OctohedralProjection( - "Cahill\u2013Keyes Butterfly", "A simple Cahill-esque octohedral map arrangement, with Antarctica left on.", + "Cahill\u2013Keyes (butterfly)", "A simple Cahill-esque octohedral map arrangement, with Antarctica left on.", CahillKeyes.lMG, CahillKeyes.lMA, 0b1010, Property.COMPROMISE, 4, Configuration.BUTTERFLY) { @@ -68,7 +68,7 @@ public class Octohedral { public static final Projection KEYES_BASIC_M = new OctohedralProjection( - "Cahill\u2013Keyes Basic", "A simple M-shaped octohedral projection, with Antarctica broken into three pieces.", + "Cahill\u2013Keyes (simplified)", "A simple M-shaped octohedral projection, with Antarctica broken into three pieces.", CahillKeyes.lMG, CahillKeyes.lMA, 0b1010, Property.COMPROMISE, 3, Configuration.M_PROFILE) { @@ -82,36 +82,53 @@ public class Octohedral { new double[] {Math.toRadians(coords[0]), Math.toRadians(coords[1])}; } }; - - - public static final Projection CAHILL_KEYES = new OctohedralProjection( + + + public static final Projection KEYES_STANDARD = new OctohedralProjection( "Cahill\u2013Keyes", "An M-shaped octohedral projection with Antarctica assembled in the center.", CahillKeyes.lMG, CahillKeyes.lMA, 0b1010, Property.COMPROMISE, 4, Configuration.M_W_S_POLE) { - + public double[] project(double lat, double lon) { return super.project(lat, lon + Math.PI/9); // apply the central meridian manually } - + protected double[] faceProject(double lat, double lon) { return CahillKeyes.faceProjectD(Math.toDegrees(lat), Math.toDegrees(lon)); } - + public double[] inverse(double x, double y) { double[] coords = super.inverse(x, y); if (coords == null) return null; coords[1] = Math2.floorMod(coords[1] - Math.PI/9 + Math.PI, 2*Math.PI) - Math.PI; // apply the central meridian manually return coords; } - + protected double[] faceInverse(double x, double y) { double[] coords = CahillKeyes.faceInverseD(x, y); return (coords == null) ? null : - new double[] {Math.toRadians(coords[0]), Math.toRadians(coords[1])}; + new double[] {Math.toRadians(coords[0]), Math.toRadians(coords[1])}; } }; - - + + + public static final Projection KEYES_OCTANT = new OctohedralProjection( + "Cahill\u2013Keyes (single octant)", "A single octant of the Cahill\u2013Keyes projection (for memory economization in the case of very large maps).", + CahillKeyes.lMG, CahillKeyes.lMA, 0b1010, Property.COMPROMISE, 3, + Configuration.SINGLE_OCTANT) { + + protected double[] faceProject(double lat, double lon) { + return CahillKeyes.faceProjectD(Math.toDegrees(lat), Math.toDegrees(lon)); + } + + protected double[] faceInverse(double x, double y) { + double[] coords = CahillKeyes.faceInverseD(x, y); + return (coords == null) ? null : + new double[] {Math.toRadians(coords[0]), Math.toRadians(coords[1])}; + } + }; + + public static final OctohedralProjection CONFORMAL_CAHILL = new OctohedralProjection( "Cahill Conformal", "The conformal and only reproducable variant of Cahill's original map.", Math.sqrt(3)/2, 0, 0b1000, Property.CONFORMAL, 3, Configuration.BUTTERFLY) { @@ -176,7 +193,7 @@ public class Octohedral { public static final Projection CAHILL_CONCIALDI = new OctohedralProjection( - "Cahill\u2013Concialdi Bat", "A conformal octohedral projection with no extra cuts and a unique arrangement.", + "Cahill\u2013Concialdi", "A conformal octohedral projection with no extra cuts and a unique arrangement.", Math.sqrt(3)/2, 0, 0b1000, Property.CONFORMAL, 4, Configuration.BAT_SHAPE) { private final double lon0 = Math.toRadians(20); @@ -324,19 +341,37 @@ public class Octohedral { { 0, -0.5, Math.PI/3, Math.PI/2, -Math.PI/2, Math.PI/2 }, { 0, -0.5, 2*Math.PI/3, Math.PI , 0, Math.PI/2, -1, Math.toRadians(-9) }, { 3/Math.sqrt(3), 0.5, 0, Math.PI , -Math.PI/2, 0, -1, Math.toRadians( 9) }, - })); + })), + + SINGLE_OCTANT(1, 0, 2/Math.sqrt(3), Math.sqrt(3), true, new double[][] { + { -0.5, 0, Math.PI/6, Math.PI/4, -Math.PI/2, Math.PI/2 }, + }); public final double fullWidth, cutWidth, fullHeight, cutHeight; public final boolean hasAspect; - public final double[][] octants; // array of {x, y (from top), rotation, \lambda_0, \phi_min, \phi_max[, \lambda_min, \lambda_max]} -// public double cutRatio; //this variable should be set by the map projection so that the configuration knows how big the cuts actually are - + /** + * array of { + * x, y, rotation, λ_0, ф_min, ф_max[, λ_min, λ_max] + * } for each face of the octohedron + */ + public final double[][] octants; + + /** + * @param fullWidth the size of the configuration in altitudes ignoring cuts + * @param cutWidth the change in width due to the cut-in lengths + * @param fullHeight the heit of the configuration in altitudes ignoring cuts + * @param cutHeight the change in heit due to the cut-in lengths + * @param hasAspect whether it would make any sense to change the aspect + * @param octants the array of octant specifications. each octant must + * specify the x and y of the pole, the central meridian, + * and bounding latitudes and longitudes of the face. + */ private Configuration(double fullWidth, double cutWidth, double fullHeight, double cutHeight, boolean hasAspect, double[][] octants) { - this.fullWidth = fullWidth; //the size of the configuration in altitudes ignoring cuts - this.cutWidth = cutWidth; //the change in width due to the cut in cut lengths - this.fullHeight = fullHeight; //and the cut sizes + this.fullWidth = fullWidth; + this.cutWidth = cutWidth; + this.fullHeight = fullHeight; this.cutHeight = cutHeight; this.hasAspect = hasAspect; this.octants = octants;