Monday, April 30, 2018

Back In The Woods (Part 4): Trunks

Before I jump into implementing tree trunks, I want to fix up a few problems from my (currently pretty simple) routine for putting trees on the map.  I put this together quickly at the end of the last post, and showed this example:
There are a few problems with this example.  First, the colors are hard-coded, so it's not picking up the map theme colors for the forest.  Second, the logic for avoiding rivers, seas and mountains isn't working.  This is because it is using the same approach I used for forest masses.  For this style of forest, I can't get so close to other map features -- I have to stay away the radius of the tree icons (or even more).

After fixing those problems I have this:
This fixes those problems, although I note that the “liut Mam" city icon is on top of some tree icons.  I'm not sure that's good, but I'll leave it for now.

Moving on to tree trunks, when I look at my example maps that use individual tree icons, most of the trunks are pretty simple:  a dark line coming downward out of the tree shape, usually about 20-25% the height of the tree shape, and somewhat bigger at the bottom than at where it joins the tree.
These have some shading, too, but I'm not worrying about that yet.

To add trunks, the first thing I need to do is turn trees into structures.  Up until this point, I've just been treating trees as an array of polygons but now I need to distinguish the tree shapes from the trunk shapes.

Once that's done I can construct a trunk as a polygon that gets broader at the base to represent the roots, e.g., something like this:
Now I draw the trunk from the center of the tree and somewhat longer than the radius of the tree.  By drawing the trunk first, the clumps will conceal the upper part of the trunk.  That gets me to this:
The "roots" might need a little tweaking but it looks like this approach will be okay.  With some rudimentary colors:
A little "cartoony" but the basic shape looks pretty good.  Let's see what it looks like on the map.  For individual trees with trunks, the icons are usually spaced out more widely.
Not too bad.  I see a few problems -- the “roots" at the base of the trunk aren't always obvious, and some of the trees aren't showing any trunk at all -- but overall the effect is pretty pleasing.

Next time I'll work on adding texture and shading to the trees.

Wednesday, April 25, 2018

Back In the Woods (Part 3): Tree Shapes

In the previous posting, I developed a basic approach to generating a roughly circular tree shape, as in these examples:
Circular tree shapes are not uncommon on fantasy maps:
However, even for deciduous trees many maps have more varied shapes, as in these icons taken from historical maps:
There's quite some variety across different maps, but one common shape is like a clump of fluffy balls (rather than just one).  Sometimes these are merged together into one shape, and sometimes they remain separate -- this is more obvious when the clumps are shaded (as in the fourth tree in the top row).  So let's see about implementing that.

To start with, I'll just generate a tree as overlapping smaller tree shapes.  Here's an initial attempt:
That's not really what I was imagining; the circles need to be smaller and more offset from each other.  But in a Bob Ross “happy accident" way, that actually looks interesting at map scale:
which is something to keep in mind.  Let me fill the clumps with white and reduce the size and increase the offset.
This is a little closer to what I'm imagining.  Some of the shapes (like the lowest leftmost one in the array) seem pretty good.  But many of them are too overlapping.  Right now I'm just randomly offsetting them from the center point, but often that doesn't move them far.  I can try adding a minimum offset.
That's a little better, but there are still lots of shapes that are too clumped and a lot of shapes that don't really look like trees.

In reality, trees aren't random shapes.  They're never bigger on the top than the bottom, or diagonal, for example.  (Well, maybe not *never* but rarely.)  After playing around a bit, I came up with this:
I'm basically stacking the clumps up in a rough pyramid.  The logic for this isn't very good, and probably wouldn't work for more than 3 clumps.  But I suspect that 3 clumps will be more than enough for this icons, so I'm going to use this until I need something better.

Drawing the clumps individually like this doesn't look much like a tree.  It looks more like a tree if I just draw the outline:
I've drawn in the clump outlines faintly so you can still see the structure of the trees, and to give a faint indication of shading.  Not every one of these looks perfect, but at map scale most look pretty good.

One drawback of this approach is that it's pretty slow.  Taking the union of two polygons (which I have to do twice on each 3 clump tree to get the outline) is expensive.

Now that I can generate a basic tree shape, I can try it out on a map.  Without tree trunks, this looks more like a top-down view of the trees.  You occasionally see maps done in this style, using many individual tree shapes to create a forest mass:
The colors are a bit bright for this map, but otherwise it looks pretty good.  You'll note that rivers are being obscured.  Right now this is using the river avoidance distance used by the forest mass style forests; they can come up much closer to the rivers without overlapping.  This method will require a greater avoidance distance.

Next time I'll look at adding trunks.

Friday, April 20, 2018

Back In the Woods (Part 2): Drawing A Tree

As mentioned last time, I'm in the process of drawing forests on maps by drawing lots of individual trees.  The first step is drawing a single tree.  And the first step of drawing a single tree is drawing the cotton candy / bumpy cloud that represents the ball of leaves.  So how do I draw that?

The obvious place to start is with a circle:
I'm using a function that makes a circle out of line segments.  But as you can see, this routine doesn't close off the circle.  If I fix that and use a curve to draw between the segments, it looks a lot more like a circle:
There's a discontinuity where the two ends meet.  I could fix that, but it isn't necessary for this usage.

I don't want every tree to be a perfectly circular blob, so I'll introduce some random distortion into the circle, by adding random offsets in both x and y to every point in the circle:
That gives me a lumpy, imperfect circle.

The next step is to add bumps to the circle, similar to the bumps on the outside of the forest masses I already draw:
In fact I can reuse the same routine I use for the forest masses.  It takes a polyline (a series of line segments) and replaces each segment with an arc.
Here I've purposely made it blocky so you see how each segment of the circle has been turned into a "bump" which is itself just a sequence of line segments.  Here's a smoother rendition:
For this example I just reused the default forest mass bump parameters.  I might want my individual trees to be more "fluffy" than the forest masses, so I can tweak that parameter accordingly:
And that's the basic approach for a simple tree shape.  If I add some random variation in the number of bumps and the size of the trees I can generate a pleasing variety.  Here's a grove of them at something closer to map scale:
That's a good start, but it's a little repetitive.  Next time I'll look at adding more variety to the basic shape.

Monday, April 16, 2018

Back In the Woods (Part 1): Introduction

Dragons Abound currently illustrates forests on the map by drawing a large mass with fluffy edges and bumps inside, as in this example:
Another approach to illustrating a forest is to fill the area with individual tree symbols.  Here's an sample of that from one of my example maps:
Tree symbols like these fit well on maps where the rest of the representation is also symbolic.

Usually mapmakers have a small number of different tree symbols to provide some variety.  If you look closely at this sample you can see that although it looks varied, there are only 4-5 different tree symbols.
 But sometimes just one symbol is used:
I don't really like this approach, but it can look okay when the symbol is tightly packed and forms an overall texture.

Sometimes map-makers use different symbols to distinguish temperate forests from alpine forests and swamps:
In this example you can see that the map has fluffy trees, pointy trees and trees mixed with plants in the swamps.

The usual approach for the tree symbols is a stylized tree shape with some rudimentary shading and a line to indicate a trunk, sometimes with a shadow underneath the tree.  But some map-makers use simpler symbols, sometimes no more than a rough brush stroke.
Over the next series of blog posts I'll work on implementing this style of forest illustration in Dragons Abound.  Obviously I'll be procedurally generating the individual trees, and I intend to tackle both deciduous (fluffy) and coniferous (pointy) trees.

Monday, April 9, 2018

Parameter Management

Dragons Abound  is controlled by a long list of parameters implemented as properties on a Javascript object.  At the moment there are about 2000 of these parameters.  There is a Javascript object that holds the world generation parameters, and another that holds the map generation parameters.  The start of the map parameters object looks like this:
var defaultMapParams = {
 // SVG rendering mode
 renderingMode: 'crispEdges',
 renderingMode: 'optimizeSpeed',
 // Color parameters
 colorsUseGrayScale: 0.10, // 10% of maps?
 colorsUseDesaturation: 0.20, // 20% of maps?
 // Saturation Range
 colorsSatRange: [.50, .70] ...
There are various problems with this approach -- finding a specific parameter in 2000 parameters isn't particularly easy, for instance.  One problem is that I often want to use a particular configuration of parameters for a run.  For example, I might want to use the parameter settings that product a map that looks like the "Skies of Fire" map:
This requires setting 186 values.  Obviously, it is impossible to do that by hand -- and then remember the default values to change them back!

My solution to that was to create something called “styles".  A style is just a set of parameter values that can be used to override the default values.  So I have a style for “Skies of Fire", which starts out like this:
  sof: {
     landPatternChance: 0,
     colorsWaterForce: [240, 228, 218],
     colorsLandForce: [225, 205, 182],
            forestMassShowChance: 0,
     oceanPatternChance: 0...
So when I want to generate a map in the “Skies of Fire" style, I just set the map style to point to the “sof" parameter values.  The first thing the program does when it starts up is look up the style and then copy all those values on top of the default values.

That worked pretty well for a while, but it soon became apparent that it would be helpful to have multiple styles.  For example, I have a style called “bestLabels" that sets parameters for the simulated annealing algorithm that places the labels to take longer and try harder to find good label placements:
      bestLabels: {
            saEnergyFactors: [500, 1000, 2000],
            saLabelQuality: 5000
To make a map in the “Skies of Fire" style with the good label placement, I need to use both styles.  So I modified start up to look for a list of styles and copy them one after the other onto the parameter object.

A problem with this approach popped up when I started generating city icons.  One feature I have in city icons is to use different styles of icons for different countries.  But when I apply a “city icon style" by copying it into the parameter object, I wipe out all the default values on the object.  The when I switch to a different style, I have a problem if a parameter is left at the value for the first style instead of being reverted back to the default.  The problem is actually worse than that, because sometimes I want to generate one house out of the icon in a different style.  It became clear that I needed a way to temporarily change parameters.

My solution was to create a function called getProp() that takes a list of parameter objects and looks through them in order to find a value for a parameter.  Thanks to the Javascript spread syntax , it's easy to write a pretty flexible function to do this:
function getProp(name, ...sources) {
 // Looks through the sources in order to
 // see if we can find a value for name
 for(let i=0;i<sources.length;i++) {
     if (sources[i] &&
         sources[i][name] != undefined) return sources[i][name];
 return null;
Rather than destructively copying a style onto a parameter object, using getProp() I can leave it separate and just include it in the list of sources ahead of the parameter object.  For example, to look for a property first on a roof, then on a house, then on a house style and then on the default parameters, I would call:
const rr = Utils.getProp('ciRoofRatiosPoint', roof, house, mapParams.houseStyle, mapParams);

Unfortunately for me, I didn't implement this approach until I started work on city icons, so it's only used in that part of the code.  Adding it into the rest of the code would seem to be very difficult -- I'd have to find every spot where I look up a parameter and replaced it with a call to getProp().  And frankly, it's kind of ugly to have getProp() all over the place.  However, Javascript is very flexible, and there's a way to seamlessly add this functionality to the parameter objects without having to rewrite all the existing code.

In programming, it's often useful to be able to go back and “retrofit" new behavior onto an existing functionality.  For example, suppose you were storing a person's age as the age field on an object:
     person.age = 100;
The way Javascript objects work, you can set the age property to any value.  But in this case, you might like to modify the behavior of the age property to complain if you set the age to something odd:
     person.age = 'young';
     // Error!
This is a case where you'd like to change what happens when you set the age property.

You can do exactly this with something called Proxy .  Proxy lets you replace an existing function with a new function -- even for some built-in functions like “getting" and “setting" an Object value.  I won't go into all the details, but for my need, the basic idea is to replace the “getting" function on the parameter values to something like getProp().  So when I get a property value by doing something like:
or like:
what will actually happen is that the params object will look through a list of styles first, just as getProp() did.  I can even make this recursive, so the styles themselves might look into substyles for a value, and so on.

With getProp() I picked the styles to look through by passing them in as arguments to the function.  (And I could do as many as I wanted thanks to the spread operator.)  When I'm doing something like
how will the params object know what styles to look through for a value for 'useCountryBorders'?

One possibility is to use Proxy to add some new functions, such as addStyle() and removeStyle(), and use these functions to maintain the list of styles currently in effect.  However, it's probably easier to keep a list of the styles in a specific property on the params object, e.g., “styles".  So every parameter object knows to look through all the objects on it's own styles property when looking up a property value.  If I want to temporarily use the “tower" style, I can do something like this:
     //  Use params
I push towerStyle onto the list of styles, do something (e.g., draw a tower) and then pop off the towerStyle when I'm done using it.

Less obvious is that if I implement a Proxy for getting a value off of my parameters object, I have to implement a similar function on setting a value on the parameter object.  To see why, suppose the default value for the showCities parameter is false, and I'm using a style which changes that value to true.  That works fine, and I get showCities as expected.   Suppose I now want to temporarily turn off the showing of cities so that (for example) the underground cities of the dwarves don't show up on the map.  To do that, I set showCities on my parameter object to false.  What happens when I next look up the value of showCities?  Well, because I have a Proxy on the parameter object, it looks into the styles and finds the value of showCities on the style -- which is still true!  When this happens, we say the value on the style object “shadows" the value on the parameter object.

To avoid this, I need to put a Proxy for setting a property on the parameter object as well.  This Proxy looks through the styles and sets the property on the first style where that property has a value.  This way, when I change a property value it won't get shadowed by another value on a style.

As I've described, my approach to parameter management has changed multiple times during development.  The current approach with styles and Proxy() seems to be working well for the moment, but I won't be surprised if I have to change it again in the future.