That was... a lot. I decided to put some inheritance into the project,
and what a rabbit hole that turned out to be!
Huh. I think that may be the first time I've ever actually used an
"exclamatory statement". What a useless structure that is!
Anyway, both MapDesigners now inherit from the same abstract super
class. Eventually, I'll get MapAnalyzer to link to that, too. I also
changed a whole lot of other things, and started inserting parametric
map capacities. That should be a fun GUI thing to figure out. I also
changed a lot of other things that I can't remember off the top of my
head. I've just been dragging chunks of code around and swimming in
errors for the past week.
I had been under the impression that there wasn't one. If so, I'm
apparently a cartographic genius. More likely I was just mislead by that
2002 Turkish paper.
I made a new program to plot existing map projections with labels (I
have yet to actually add the labels). I also moved some things around,
implemented Aitoff, and found a bug in my Newton-Raphson Approximation
that was making it converge slower (how it still managed to converge to
the right value is totally beyond me).
I implemented the Tobler projection using values from Tobler's paper,
Numerical Approaches to Map Projections and spline interpolation. I used
the apache commons' cubic spline solution, which felt kind of like
cheating, but splines are way more complicated to solve for than I
thought, so I don't feel that bad.
It's also not actually equal-area, so not sure what's up with that. I'll
probably go looking for an iterative solution to try to deal with that.
Either way, this is a great projection.
I also move some methods and classes around.
I refactored everything (assuming I actually understand what the word
'refactoring' means, which I think I do, but I'm not sure. I'm too lazy
to check). There are fewer duplicate names, corresponding information is
closer together in general, the code has less redundancy, it's easier to
add new map projections, and classes are grouped more effectively and
more logically. I've now switched from using Strings to represent map
projections to using an enum (remember when I was using separate
classes? Wow, that was trash!). I was also going to combine the
MapDesigners and MapAnalyzer with some inheritance type stuff, but I
think that's content for another commit.
My tetrafillet projection is actually kind of good! It's not really
continuous like most of the projections I make, but I like it. I think
it's cool. And it's finally objectively better than Winkel Tripel.
I added gradient descent to the optimizing program in the hopes of
making it faster, which kind of worked, I suppose. I also made some of
the tolerances smarter on some of the iterative algorithms, and took a
few terms off of the Dixon McLaurin Series. I also have Lee centering
its Taylor Series on points closer to the points, so that's more
accurate at the poles now. And I made Tetragraph have actual numbers
attached to it rather than that 1.1 I had from guess-and check. Oh, and
I got rid of Eliptabola because it was apparently discontinuous or crazy
stiff or something, because gradient descent on it would always diverge
to NaN, and it wasn't that great of a projection, anyhow.
I implemented the Lee Conformal Projection, and let me tell you, it took
a lot of work. Oh, also, I tried another family of pseudo-azimuthal-ish
projections that just kind of sucked. I think I'm going to try
optimizing some tetrahedral projections next. Hence the Lee projection.
I used a 28th-order McLaurin series for the Lee projection, so it
doesn't actually tesselate perfectly. I think I might have entered a
number wrong, because seriously?! The 28th order with six decimal places
of precision wasn't good enough? Anyway, the series was a suggestion
from Lee himself in the paper that I read on JStor, that I had to make a
JStor account for, because I couldn't get the equations literally
anywhere else on the internet. NGAHHH!
I implemented and optimized my family of hyperelliptic projections.
They're okay - not overwhelmingly better or worse than Robinson and
Winkel Tripel. They have an invertible and differentiable formula,
though, so in that sense, they already are better.
The MapOptimizer plots some things now. I rewrote a bunch of MapAnalyzer
to work with functional interfaces instead of Strings in preparation for
creating new parametric map projections that will be defined only with
lambda functions.
I started a new Application that will optimize new map projections.
Right now it's just a plot, but soon, it will generate new parametric
map projections and compare them to established ones.
I fixed the Robinson Projection. I just used fewer values for the
interpolation. It's still not perfect - you can see waves of distortion
in the map analyzer where the polynomial interpolationis being wonky -
but it's good enough for now.
I also realized that by my metrics, Robinson is objectively better than
Winkel Tripel. I thought there must be something wrong with my
calculations, but upon closer inspection, I realized it's true. Winkel
Tripel was adopted by NatGeo in 1998 because it "reduces the distortion
of land masses as they near the poles," but in fact, Winkel Tripel makes
the poles look even larger than Robinson does! Furthermore, while shapes
near the poles are slightly better for Winkel Tripel, it severely skews
landmasses near the Prime Meridian. NatGeo is just wrong, and I can
prove it with math!
What's more, I realized that now that I have this robust algorithm, I
can use it to invent more map projections! I can optomize
pseudocylindrical and tetrahedral projections to generate the most
accurate map projections the world has ever seen. This is going to be
fun.
I made a robinson projection, but if you look extremely closely right
around 45 degrees north, everything is extremely distorted at small
scales. This is because of Runge's phenomenon. Honestly, linear
interpolation would be better than polynomial for this. I don't know
what Arthur Robinson was thinking using Aitken for this. Give me another
commit or so to figure this out.
I set it to use HSB instead of RGB. Now, darker areas have more angular
distortion, red areas are compressed, and blue areas are dilated. I also
made some neat graphics.
I made it stop throwing NullPointerExceptions, and I got it to measure
angular distortion as well as areular distortion. Angular distortion is
indicated in red.
So, in studying the original Winkel Tripel equations again yesterday, I
stumbled upon a scientific paper containing the Newton's Method inverse
map-projection solution equations, as well as the partial derivatives of
all the Winkel Tripel projections. After reading it over, incorporating
some of their simplified equations into my code, and then noticing
several glaring problems with my own solution (namely my trash initial
conditions), I finally solved for the inverse of the Winkel Tripel
projection! Feel free to raster it up!
The JavaFX thing wouldn't really have worked for me given that I needed
to transform the image, not just display it. I'm still salty I didn't
find out about that sooner. Anyway, I got it all to work besides the
complex number ones. I'll figure those out in a bit. I also haven't
tested saving yet, but I'm sure it will work perfectly on the first try.
I added a progress bar so you can see just how slow my program is. I
also added jpg image saving, since that apparently works now, renamed
the .jar, and fixed some bugs with image sizes. And look! It actually
looks like an application now!
I've decided to give up on replicating the AuthaGraph projection. I'm
pretty close to the actual projection, and while mine is not
authagraphic, I think it's more authagraphic than the actual AuthaGraph
projection. Of course, I can't really tell, because I can't find an
AuthaGraph map with Tissot's indicatrices on it.
In attempting to solve for the AuthaGraph projection, I made something
that is, in my personal opinion, better: a compromise tetrahedral
projection! It's not authagraphic (though, technically, neither is
AuthaGraph), but it distorts shape far less than AuthaGraph does. I'll
still try to solve AuthaGraph, maybe even modify it to make it, you
know, authagraphic, but I really like this map projection I came up
with.
Turns out some of those garbage IDL-zero conventions were lurking in my
code. Typical. Cut off one head of the evil conventions hiding in my
code, and two more grow in it's place. Well, I'm almost certain my
conventions are correct now, and am ready to tackle AuthaGraph again.
So, it turns out that one of the reasons I was having such trouble with
AuthaGraph was that I had a sign convention where south was positive and
the international date line was zero. So, I fixed that, because that was
awful. It should be easier for me to figure out polyhedric projections
now. Mind you, AuthaGraph doesn't work at all right now. It's just not
even close right now. Don't worry - I'll work on that.
I tried to make MapProjections faster, but it didn't work. The GUI looks
nicer now, but a bunch of functionality is gone.
I also did something with wormhole, apparently.