Tuesday, October 24, 2017

Labeling Islands (Part One)

I'm going to move on (temporarily) from labeling coastal features, and start labeling islands -- or at least groups of islands.  Dragons Abound has a couple of different ways to generate groups of islands.  Some are based on cones (volcano islands, like Hawaii) while others are just noise-based splotches.  In either case, they are generated as a clustered group of individual islands, although sometimes they overlap and run together.

My initial notion for labeling these island groups is to draw a path around the entire island group and then attach a path label for the islands to that path.  To do that, I need to keep track of all the islands in a group as I create them and then create a convex hull from those points.  In simple terms, a convex hull is just the minimal line that you can draw around a set of points if you are only allowed to draw from point to point.  It turns out that d3 has a function to calculate the convex hull from a set of points, so it's only a few minutes work to add this to Dragons Abound:
The green line here is the convex hull drawn around the islands.  The "Group Islands" label has been attached to this path and placed by the simulated annealing algorithm.  The only complexity is setting the offset properly so that the label will fall on the outside of the path.

Here's another example:
Note that in this case "Nun-Bun" was not included, since it was created by a different part of the terrain generation.

Here's an example where it doesn't work very well:
There are a couple of problems here.  First, some of the islands included in the group appear to be off-screen.  Second, the area for the group seems to be too large to look good as a "group".  The first part is easy to fix by adjusting the algorithm that places the islands to avoid any location that won't appear onscreen:
The second problem is that the total radius for a group of islands of this type (these happen to be "cone" islands like volcanoes would produce) is set too large.  Again, it's easy enough to put in a more reasonable range:
Here's another broken example:
For some reason, the island group includes a good chunk of land.  What happened here?  Generating the map without the islands makes it obvious:
The islands happened to get generated close enough to the shore (and other existing islands) to fill in and become part of the land.  I can address that by forcing islands to be further off-shore:
A final optimization is to make these labels prefer to be at an angle near zero.  This effectively tries to place them either above or below the island group.
Some differences here due to me tweaking the island creation algorithm, but you can see that the label has migrated to be underneath the island group.

And that's about all that's necessary to label the island groups.  The functions I'd built up for labeling rivers and coastlines provided almost everything I needed "out of the box" and with a few tweaks looks pretty good.  Next I'll look at labeling individual islands, like the two above the "Lost Coast" label in the above image.

No comments:

Post a Comment