It's not as simple as you think.
The goal of the project: to write a space-filling algorithm using hexagons of different
sizes. While it was an engaging project in itself, the motivation behind it was perhaps
Waldo Tobler (1963) stated that "a basic truism of geography is that the incidence of
phenomena differs from place to place on the surface of the earth." Cartograms are one way
to show the uneven distribution of a phenomenon on this surface.
There are many criteria that can guide the creation of successful cartograms. Simply,
though, good cartograms must be:
- not unnecessarily complex
- accessible to viewer
- able display a large quantity of information
- interesting to the eye
However, there's a natural tension between criteria 3 and 1 (and 2, to a certain extent).
So, the goal is to strike a balance between these two criteria.
In a slightly different vein, consider the geodemographic theory that people behave in
accordance with their environment not as it actually is, but as they believe it to be. Areas
with greater diversity have more variable data for many of the metrics we might care to
visualize. So, the goal is to create a visualization that is capable of showing more
detail in highly-diverse areas while reducing detail in more homogenous regions.
Now, how might we determine broadly where those diverse areas are? There's a lot of science
behind this, but coastal areas tend to have higher diversity than non-coastal areas. They
also tend to have higher population density, meaning lots of data in small spaces of the
map. So, we want a map projection that simplifies non-coastal areas (reducing map
complexity) since the data there is less variant, but allows us to see coastal areas in more
depth. Consider the simple example at left.
Here, the second map more closely mimics the original map, and it uses fewer squares.
However, squares are pretty boring. Hexagons are one of the most space-efficient shapes, and
can stack more easily than squares. So, I decided to write a space-filling algorithm using
However, it turns out that the things that make hexagons so effective (for example, 120°
angles) also make them very difficult to work with. The first problem I encountered was how
to define the space in a way I could work with easily. The best way that I thought to do
this was to define the shape by a number of vertices, and then connect those vertices with
lines. I started working with the shape of Australia because it was small enough to not be
overly complicated but detailed enough to still provide interesting results.
The next task was to find the largest possible space inside the shape that I could place a
hexagon. I first defined the coordinates for the center of the shape as the midrange of the
array of x-coordinates and the midrange of the array of y-coordinates of the shape.
The reason I used midrange and not mean or median is that the vertices are not spaced evenly
around the continent, so the mean and median would be biased towards areas with more detail
(more vertices). Once I defined the center of the shape, I constructed lines to each of the
vertices and found the smallest line. I then defined that line as the radius (center to
vertex) of the central hexagon.
After defining the radius of the hexagon, I drew the hexagon as a series of points defined
by the radius and the center (n and x,y).
However, this is clearly not the largest possible hexagon that can fit in this space. I then
defined an expandpolygon() function which incrementally increased the size of the hexagon
and moved the center accordingly. I found the distance from the top, bottom, left, and right
edges of the hexagon, and then found the smallest and largest of those distances, and then
expanded the polygon a little bit accordingly. (Originally I had a problem with overshooting
the edges, but then I added parameters for when the polygon could expand.) This problem would
have been simpler if the smallest side was opposite the largest side, but this was not always
true and I had to account for all combinations of the most and least room. For example, if
the most room to expand was on the right, move the center of the hexagon to the right by one
and increases the radius enough so the left side of the hexagon stays in the same place.
The next task, placing more hexagons, was different because instead of using the original
coordinates as boundaries, the shapes had to fit where there weren't already hexagons, so
had to take a portion of the array defining the outside shape but use the sides of the hexagon
for other boundaries, but from there the function to expand the hexagon was similar.
If desired, the code that corresponds with the above explanation can be downloaded
. To someone who doesn't know what
they're doing, it's long and impressive. To someone who does, it's probably nonsensical and
unwieldy. I wouldn't know - I belong to the former group. Parts of it are commented for your
viewing pleasure. Other parts are not. Sorry.