Friday, February 1, 2019

Fractal magic

So we've put together some rather amorphous continents and some chains of mountain ranges with associated land, but it all looks a bit blobby. It's time to introduce a completely new way of making land shapes, which can combine with what we've got to add greater variety.

Fortunately we already have one - the diamond-square fractals that we looked at before. I said then that a fractal map of that kind isn't much good as a world map, but we can use it to improve the world map we've got by combining them. In particular, the fractal works well if we subtract it from the continental map. We do this very cunningly with two fractal maps.

Fractal map A is the one that will be subtracted from the continental map. The lower the value of any given point on Fractal A, the more it will reduce the corresponding point on the continental map. But  this is modified by the corresponding value on Fractal B. The higher that value, the more Fractal A affects the continental map. This makes sure that the effect of Fractal A is varied and not applied across the board, so we retain a good variety of terrain styles.

Here is the continental map we ended up with at the end of the previous post:


And here is the fractal map we'll be using as Fractal A:



And this is what happens after we merge them:


You can see that the map has become a lot more interesting. The big blobby continents have been broken up. We now have much more varied styles of coastline, with inlets and inland seas. Various new islands have appeared.

However, we also now have areas of sea that aren't connected to the main ocean at all. That doesn't look very good. On Earth, large unconnected seas like that almost never exist - pretty much the only example is the Caspian Sea, and even that isn't straightforwardly sea. It is a weird combination of genuine oceanic plate (deep water) with continental plate (shallow water) and varies dramatically in salinity accordingly.

It would be much better if we could get rid of these unconnected sea areas altogether (I'm planning on adding endorheic lakes soon, which would allow Caspian Sea-style bodies of water, but haven't done it yet). To do this, UW needs to be able to identify a body of water on the map that is sufficiently large to count as the ocean, and then turn into land any bits of water that aren't connected to it.

This means we need a flood fill function. UW needs to grab a point of sea at random and perform a flood fill on it. If that fill passes a certain size, UW declares that the ocean. It then goes over the map and removes any bits of sea that weren't included on its flood fill pass, turning them into land.

I initially wrote a recursive flood fill function, since that's fastest, but unfortunately it overflowed the stack quite often and caused the computer to crash. Some of the maps that UW generates are just too complicated, causing too many recursions of the flood fill. So I had to rewrite it as an iterative function, which is inevitably slower, but perfectly stable. I'm secretly quite pleased with my flood fill function, which isn't the fastest one ever created but has lots of cunning little nips and tucks to make it reasonably quick.

This is what our map looks like now:



I think this is starting to look pretty decent. We have a good variety of land masses of different sizes, with different-looking coastlines. We have a few major mountain ranges in locations that don't look appallingly misplaced. There are still some more touches we need to add, but this is not a bad base already, in my always humble opinion.


No comments:

Post a Comment