I want to apply this to draw a forest on a map as a mass of trees, like a simple version of this:
The first step is to get the basic shape of the forest on the map. This is surprisingly complex. First of all, I have to generate biomes on the map. I talked about that in this posting. Here's my usual mountain map with biomes colored in:
The next step is to get paths representing the edges of the forest. The basic idea is to look at every location on the map. If a location is a forest, and a neighboring location is not, then the edge between those two locations should be part of the forest edge. Identifying those edges is not too difficult, but chaining all the edges together to create continuous paths is a bit more challenging -- particularly because you cannot count on finding the edges in any particular order. This general problem -- finding the edges in the world where some condition changes -- comes up fairly frequently. For example, the coast is just where the height of the land changes from positive to negative. So it's useful to have a generalized function that takes a condition and returns all the edges where that condition changes. So I can use that function to identify the forest edges.
At any rate, once I have all those edges I can draw them on the map.
Once I have the paths for the forest edges, I can draw them in using the cloud effect for the edges instead of straight lines. Here's the first attempt:
At first glance, that's not too bad, although there are clearly some problems. In various places (e.g., on the left side of the middle-bottom), you can see that the woods outline has "loops" in it. In the middle upper-left, there's a spot where the bumps are going the "wrong way" -- the bumps are pointing into the forest rather than out of it. And in the upper-right you can see that the size of the bumps varies pretty radically from tiny to much bigger.
Some of these problems can likely be fixed by simplifying the forest edges. The edges you get when you subdivide the map on a condition tend to be pretty complex, so I already have a couple of functions to simplify paths that I've used on things like the coasts and rivers. One smooths out the path, eliminating most small sharp deviations. This will probably fix most of the loops in the edges.
The sections of the map where the bumps point the wrong way are probably where the path for the edge of the forest goes clockwise instead of counter-clockwise. (Or vice versa.) To fix that, all I need to do is detect when the path is going the wrong way and reverse it. But how can you tell if a path is going clockwise versus counter-clockwise? I don't entirely understand the method myself, but you can find it discussed in this Stack Overflow question. Applying a version of that and reversing the counter-clockwise paths gives me this:
If you look at the "hole" in the forest you'll see that the bumps now point in the right direction. (There's still a broken forest in the upper-left that I didn't notice until later; that was a bug that I eventually worked out.)
In this run I accidentally wrote the forest outline on the wrong layer, so you can see some of the forest edges where they normally would not be displayed, such as along the coast. Because the forest comes all the way to the coast, the bumpy edge of the forest mostly is drawn out in the water, where it is normally masked away and not seen. Most fantasy maps back the edge of the forest off a bit so that it ends before the coastline, so let me address that.
To pull the edge of the forest back from the coastline, I treat forest locations near the coast as a different biome, which effectively draws the edge of the forest in some distance from the coastline.
Overlapping forest symbols and mountain symbols makes a mess, so most fantasy maps also avoid drawing forests in the mountain areas. This is a bit more difficult. The obvious approach is to avoid all the locations that are above the minimum mountain height, much the same as I did with the coast.
That's quite busy, but you can see that it has mostly pushed the forest back away from the mountains. Here it is with the bounding boxes removed and the spacing a little tweaked:
So that's the basics. This came together much more quickly than I expected, thanks in part to being able to reuse a lot of the path code I'd already developed. Next time some tweaks and improvements.
Looks cool! You've solved some difficult problems here. I do thing though that the edges of the forests near the mountains is a bit jagged and 'square'. Perhaps some kind of overall smoothing would soften that out a bit?
ReplyDeleteI think that's mostly just an artifact of this map, but if it's a problem I'll add some perturbations or smoothing as necessary. (Although if you look at the example map at the top of the post, you'll see that it also has some "square" features.)
ReplyDelete