Showing posts with label #biomes. Show all posts
Showing posts with label #biomes. Show all posts

Tuesday, October 2, 2018

Swamps

In previous postings, I developed a “hachure" style of grassland marker:

Confusingly, the same marking is also often used to indicate a swamp, as in this map of the "Black Coast" by Cartographer's Guild mapmaker Diamond:
Another common swamp marking is a variant on these hash marks that adds a horizontal line at the bottom of the hash and mixes in some simple lines, as in this stylized example also from Diamond:
Here's a more hand-drawn look of this approach on the Tamriel from Misty Bee:
Obviously if you use these hash mark symbols for swamps, you can't also use them for grasslands, so on these maps grasslands either go unmarked or mapmakers invent some other symbol.

To create the basic swamp symbol, I can take the hachure I used for grasslands, bring the bottom of the individual grass blades together, and add a solid line underneath:
(Although these also look a little like sagebrush or some such to me.)  On my reference maps, these swamp symbols are mixed with simple lines.  I can do that by randomly drawing lines instead of the swamp symbols.  Here's an attempt:
This looks somewhat better, but there are too many lines.  The problem is that the lines don't take up much room on the map, so the routine that is filling the swamp area can pack in many more of the line symbols than the hachure ones.  To address that, I need to treat the line symbols as if they take up more room than they actually do.  (Oddly enough, the easiest way to do this was to draw an invisible cross-line on each of the lines.)
This looks more swampy.  My own mental picture of swamps includes bubbles of swamp gas rising up from the ground, so let me try adding some bubbles.
That seems to have some potential.  Some tweaking to add multiple bubbles, different sizes, etc:
Along with bubbles we might get fumes, which I'll indicate with rising curvy lines:
You might also notice some “popping" bubbles in there, although they're not super distinguishable at this scale.  Mixing these different options gives me a variety of swamp symbols.

In the examples above, I was actually marking grasslands as swamps, since that was the quickest way to test the new symbols.  But currently Dragons Abound doesn't actually create any swamp biomes on the map.  So I need to add that.

As it turns out, before I can add swamp to the map I need to fix a part of my biome generation.  The last step in biome generation is “smoothing."  Smoothing averages out the biome of each location based upon the biomes of its neighbors.  Without this step, biome generation produces splotchy biomes, particularly in areas that are on the edge of being either (say) grasslands or forests: 
A certain amount of splotchiness is interesting, but too much makes the map messy and eliminates the chance of having features like large, impenetrable forests or vast swaths of prairie.  Like everything in Dragons Abound the amount of smoothing is controllable, but typically I do some fairly aggressive smoothing:
Here you see a number of effects of the smoothing.  First, cities have ended up in different places due to the change in biomes.  Second, the holes inside the dark green forest have been eliminated.  And lastly, there's now an intermediate shade of green representing “deep grass".  All this happens because of the mathematical average between the biomes.  Forest is 4, deep grass is 3 and grass is 2, so when neighboring locations are averaged together the pockets of grass in the forest turn into more forest, and along the edges of forest and grass you get deep grass, and so on.

However, this only works if you have a very nice numerical progression of biomes.  A progression like “desert - grass - deep grass - forest - jungle" works pretty well, but where do you fit tundra or swamp into that progression?   You have to be careful that the average between two biomes makes sense.  If you (say) put swamp in the progression above jungle, swamp next to grass might average out to be forest, even though that would make no sense ecologically.  So it's probably best to get away from relying on a strict numerical progression of the biomes and mathematical averaging.

Instead, to smooth out the biomes I can set each biome to be the mode (most common choice) amongst itself and its neighbors.  So if I have a grass location surrounded by three forest and one grass locations, the mode will be forest.  With this sort of smoothing, if the map has swamp next to grass the smoothing won't introduce spurious forest at the edges.

Here's the map with a moderate amount of the new smoothing:
Note that no deep grass has been created between the forest and the grasslands.  I'll need to modify the biome generation to create that rather than relying on smoothing.  That's fairly straightforward, just adding deep grass between forest and grasslands:
This may be too much deep grass but that varies from map to map based upon the different generation choices.
(Here deep grass is being shown with green color and hachures.  Grass is not indicated.) 

Now that smoothing is fixed, I can move on to adding swamp biomes to the map.  Where should swamps appear on the map?  Well, according to Wikipedia:
swamp is a wetland that is forested.
And a wetland is:
wetland is a distinct ecosystem that is inundated by water, either permanently or seasonally, where oxygen-free processes prevail. [...]  There are four main kinds of wetlands – marshswampbog and fen (bogs and fens being types of mires).
By those definitions I think I really want to mark any wetlands, not worrying about the distinctions between marshes, swamps, bogs, etc.  Those occur in areas where there is lots of water, little slope (so that the water doesn't just flow away).  Most of the biome decisions are driven by precipitation and temperature, as in the typical Whittaker diagram:
But for swamp, when I say “wettest" area I'm talking about the amount of water flowing through that location, not the amount of precipitation falling in that location.  This is called the flux, and is used to determine where rivers are located.  I don't want to use just the flux in a location to decide if a location is a swamp, because then I'll just get swamps along every river.  So I'll look at the flux in a small radius around each location.  And the areas where there's a lot of slow-moving water on the ground will become swamps.

As a further refinement, if I want (say) 5% of the map to be swamp, I'll find 2.5% of locations using the above algorithm, and then I'll add another 2.5% of neighbors of those locations.  This will help avoid a situation where I get lots of tiny one or two location swamps scattered around the map, and instead give me clumps of swamp.

Here's an example:
The swamp here is at the confluence of two slow-moving rivers.  There's also a mostly-swampy island on the same map:
You might notice in the previous two images that there are cities in the swamp.  That's probably somewhat unrealistic.  It shouldn't be impossible to have a city in a swamp, but that's generally not a good location.  I'll add a slight penalty for swamps to the algorithm for placing cities:
And now the city is placed well outside the swamp.  This is controlled by a parameter, so on some maps cities may be much closer or even occasionally inside of swamps.  And when I add lizardmen (*) they'll probably prefer to live in the swamp.

(*) Of course I'm going to add lizardmen.  That was never a question.



Monday, September 17, 2018

Grasslands (Part 3)

(Note:  This was actually posted out of order with #4.)

At the end of the last posting, I had a basic grassland/swamp symbol working, and was able to place it on the map in a reasonable way.  The basic symbol looks like this:
In this posting I'll look at adding some variation/interest to the generation of the symbol.

The first step is to vary the size of the symbol to be wider or narrower and have fewer or more “blades" of grass.  If you examine this example use:
you can see that the individual symbols have anywhere from three to ten blades.  There are a couple of ways I could program this variation.  I could pick a random width and then figure out how many blades could fit, or I could pick the number of blades and let that determine the width.  Either choice will be made more complicated if I allow the size of the blades and the gap between them to vary.  At any rate, I chose to pick a random number of blades and then let that determine the width.
The number of blades is chosen at random.  But a random distribution -- where every number of blades is equally likely -- is probably not the most realistic/artistic.  A better distribution would be weighted toward the middle of the range, so if I allow (say) 3-8 blades, most of the clumps will be 5 or 6.
I can also add some variation to the arch of each clump.
(I don't want to let the bottom get completely flat, since that will be the basis for the marsh symbol.)

Another tweak is to make the top curve a little asymmetric.  This is accomplished by moving the control point of the Bezier curve a little bit off-center.
As you can see, a few of the symbols now have a bit of a sway to the right or the left.

Likewise, I can tweak the individual blades a bit to either side so the spacing isn't quite so mechanical.
This has a pretty big impact on making the symbols look more hand-drawn.  If you compare the map-sized symbols in this picture with the one above you'll see that the ones above look much more mechanical.

I can vary the line width in a similar way.
Here I'm just varying the starting width of the stroke -- they all taper off to zero.

Finally, I can make the individual blades a little shorter or longer on either end.
The last (?) thing I'll do is add a little arc to the blades.  This is probably overkill at map scale (not that overkill has ever stopped me before) but is at any rate easy enough to try out.  Bending the blades just requires turning the straight blade lines into arced ones using the same quadratic Bezier curve routine I've used previously.
Here I've just used the same offset for every blade.  Which is good for producing eyelashes but maybe not so good for grass.  I need to make the offset switch over at the middle of the icon, so that all the grass bends away from the middle.
I'm not using too much “bend" here but it does give the grass a more lifelike look.  Here's a side-by-side comparison between the original symbols and the “hand-drawn" symbols:
Next time (actually last time) I'll take a look at using these symbols on the map.

Wednesday, September 12, 2018

Grasslands (Part 4)

Last time I finished up the basic generation of grassland symbols, which looked like this:
Now I'm going to look at placing these on the map.

Previously I made an initial pass at placing these symbols on the map, and had something like this:
In the upper part of the image I just placed symbols throughout the grasslands.  But that ends up clashing with a lot of other map elements; in the bottom half I added some code to make the grassland symbols avoid forests, mountains, rivers and coastlines.

Here's an example of a map using the more hand-drawn symbols:
The changes I've made to make the symbols more hand-drawn help quite a bit, but I find the overall effect to be cluttered and unappealing when applied over the entire map.  This is probably one reason you rarely see it used this way by human map-makers.

One way to address this is to reduce the visual impact of the grassland symbols by coloring them to match the land and reducing their opacity:
This ends up looking like a land texture.  This is an improvement and a useful option, but I still don't like the overall look.

The real problem here is having the same symbols over most of the map.  Generally speaking, I think the best fantasy maps have a lot of variety, so that every spot on the map looks like there's something interesting happening there -- not just a repeat of stuff that is everywhere else on the map.  And visually, if you have something happening over most of the map, it's better to leave that blank (background) to not distract from where things are different.

I can think of a couple of ways to reduce the amount of grasslands in an interesting way.  The easiest is to avoid putting symbols near cities.  The idea here is that the areas furthest away from the cities are the unsettled, more wild areas of the map, so we'll use the grasslands symbol to indicate that.
I'm doing something pretty simple here -- just eliminating grassland within a fixed distance of a city.  This works pretty well to make the grass more sparse and the map more interesting.  It also has a couple of drawbacks.  It's hard to pick a fixed distance that works well on all maps.  And it treats all cities the same way, where big cities probably should push back the wilderness more than smaller cities.  In the long run, I plan to have something in the world generation that decides what is really wilderness and what is settled.

I've colored the land green for these illustrations, but it's interesting to look at a map with a traditional brown land color:
This has quite a different feel to it.  To me, adding the grassland symbols causes me to see all the tan land as desert or wasteland.  Making the symbols green isn't any better:
Most of the reference maps I have that use this kind of marking for grasslands are black and white, or have a green land color, probably to avoid this problem.

I have a few example maps that use color to indicate biomes (i.e., grasslands versus desert).  I haven't done a lot with coloring the map to reflect the biomes, but I do have a simple version implemented that I use primarily for debugging.  It just fills in light green for grass, yellow for desert, dark green for forests, and so on.  If I turn that on and use the grassland symbols it looks like this:
It's nice to have a clear differentiation between the biomes on the map, especially where deserts meet the grassland.  On the other hand, deserts are actually fairly rare, so it isn't every map that will have a nice differentiation like this one.  But a problem with putting biomes on the map like this is that there's plenty of grasslands biome that doesn't get symbols, because I'm still avoiding putting grassland symbols where they would clash with rivers, the coast and etc.  As an alternative, I can  apply the biome coloring only where there's a grasslands symbol:
This looks pretty good, although it still has the problem that marking grassland in this way makes it seem as if everything else on the map is desert.  I'll continue to experiment with this and see if I can find some more appealing approaches.

Meanwhile, I can look at some variants for the grassland symbol.  One variant is to increase the height of all the blades, to make the tuft more leggy:
The opposite variant is to take away all the arc in the blades and make all the blades the same length:
These short straight tufts is an approach I've seen some human map-makers use.  I think both of these variants look pretty good.

That's basically all for this kind of grass symbol; next time I look at marking grasslands with a different sort of symbol.

Wednesday, September 5, 2018

Grasslands (Part 2)

This post I'll be working on generating graphics to represent plains or swamps that look like these hash marks:
It turns out I've already done something like this before, when I generated something similar to implement hachures.   That word might not be familiar, but you'll recognize hachures easily enough -- they are the curved hashes used to illustrate elevation, as in the two hills on this map excerpt:
If you compare these hachures to the field symbols above, you'll see the similarities.  To generate hachures, I created a curve, calculated the normal to the curve at various points, and then drew various length lines along the normals.  That worked fine, although I could never really get hachures to look good on the map, so I ended up discarding that code.

With some of the code I've written since hachures I have an easier way to generate these sorts of symbols.  I can create two different curves between the same end points, split each curve into an equal number of points, and then draw hash lines between matching points:
That's a mockup, let's work on the real thing.  The first step is the two outer curves.  In this case I'm going to use a quadratic curve -- this is a type of Bezier curve with one control point.  To create a symmetrical curve with height H, you place the control point above the center of the curve at twice the height H:
Once you have the start and end points and the control point, you can use the equation provided here to generate points along the curve.  This is a parametric equation -- the input is a number from 0 to 1 which represents the percentage along the curve, and the output is the point on the curve at that (percentage) location.  So it's very easy to use this to generate some number of points along this curve, as I need to do in this case.  All together, the code looks like this:

// See
// https://stackoverflow.com/questions/5634460/quadratic-b%C3%A9zier-curve-calculate-points
// t = [0, 1]
function calcQuadBPoint(start, control, end, t) {
    const x = (1 - t) * (1 - t) * start[0] + 2 * (1 - t) * t * control[0] + t * t * end[0];
    const y = (1 - t) * (1 - t) * start[1] + 2 * (1 - t) * t * control[1] + t * t * end[1];
    return [x, y];
};

// Make a quadratic arc from pt1 to pt2 that rises to a point h above
// the midpoint, and return it as a polyline with num points.
function makeQuadraticArc(pt1, pt2, h, num) {
    // Calculate the control point
    const x1 = pt1[0];
    const x2 = pt2[0];
    const y1 = pt1[1];
    const y2 = pt2[1];
    const cx = (x1 + x2)/2;
    const cy = (y1 + y2)/2;
    const dx = (x2 - x1)/2;
    const dy = (y2 - y1)/2;
    const dd = Math.sqrt(dx*dx+dy*dy);
    const ex = cx + (dy/dd)*h*2;
    const ey = cy - (dx/dd)*h*2;
    const cp = [ex, ey];
    const result = [];
    for(let i=0;i<num;i++) {
 result.push(calcQuadBPoint(pt1, cp, pt2, (i/(num-1))));
    };
    return result;
};

(This code should work for any start and end point; if you just need to do it for an axis-aligned arc like I'm doing here the code can be simplified.)

So I can use that to draw two curves between the same points, one a little higher than the other.
Looks good so far.  In this case, I don't actually want the curves, I want points along the curve.  So let me draw points corresponding to where the lines would go:
This shows a problem -- if I draw lines between the points, the lines will all be vertical!  How did that happen?  If the curves are split into equal-sized pieces, the points on the top curve should be spread further apart (because that curve is longer).

Well, it turns out that the parametric function above is not linear.  The points it generates will not be equally spaced along the curve -- basically the points are farther apart where the curve is steep and closer together where the curve is shallow.  The result is that the points line up even when they're taken from different curves, as I'm doing.  

So how do you get equally spaced points?  That turns out to be hard.  The most practical approach is to sample a bunch of points along the curve (say, 100), calculate the distance between the points, and then resample to find points that are equally spaced.  But that's a lot of work to draw a clump of grass.

What I need to do is either spread out the intervals around the center on the top curve or compact them on the bottom curve.  As it turns out, d3 has functions that do just this -- they take numbers on a range of 0 to 1 and remap them to the same range but with different intervals.  They're called easing functions.  Maybe I can pick an easing function that will do what I need.  The idea is to put the input for the parametric function through the easing function before using it for the upper curve.  So for example, if I'm generating the point for 0.25 on the bottom curve, I'll use the easing function on 0.25 to get a new value -- say, 0.17 -- and then use that for the upper curve.

For this to work, I need an easing function that “slows down" values before 0.5, and “speeds up" values after 0.5.  After some playing around trying out various easing functions, here is d3.easePolyInOut with an exponent of 1.5:
This does what I want -- the points on the top curve are now spread out.  And now the lines will fall away from the center outward.  Higher exponents to this easing function make the lines fall away faster.

Now I will stop drawing the top and bottom line and the points and just draw lines between the points.
And that's the basic shape.  It even looks pretty good just like this at map scale.

Before I go any further, I want to add the code to display the symbol on the map to get a sense of how it looks and refine the size.  It's always pretty challenging to get a nice placement of symbols in a case like this.  Obviously you want to spread out the symbols a bit so they don't overlap, and you want to scatter them in a more-or-less random way.  But you also have to take care to avoid a lot of the other map symbols.
The top image just places symbols into the grasslands and you can see this results in symbols clashing with the forest, the coast, rivers, cities and the mountains.  In the lower image I try to avoid all those things.  Before I place a symbol, I check it's distance to the nearest forest, mountain, etc., and skip it if that's too small.

Taking a look at this initial version, I'm not sure I like using this to denote all grasslands; there are a lot of grasslands on the typical map and this makes the map pretty busy.  We'll see.  Next time I'll work on making the symbol a bit more varied.

(N.B.A few weeks after writing this post, I realized I needed a little more control over the geometry of the hachures, and ended up changing the way I generate them.  The new method still has the same upper and lower curves to find the endpoints of the individual blades, but now the curves can be separated with some height (meaning the ends of the curves don't always touch) and the curves can be different lengths -- which eliminates the need to use an easing function.)