Wednesday, March 27, 2019

Better basins

Although the endorheic lakes are working fairly well, I wasn't really happy with the river networks around them, even on those occasions when there weren't any bugs:


While there aren't exactly any problems with this map, I think the drainage area for this lake should be wider. Endorheic lakes typically appear in the middle of large arid areas where all the water flows to a central point. So those other rivers that pass fairly close to this lake, but flow past it and ultimately into the sea, look a little odd.

As described in the previous post, endorheic lakes are made in two stages. First, during the river calculation stage, we place small areas of sea at random points where rivers are flowing through deserts. We also adjust the flow directions of the surrounding cells to ensure that they are all flowing into these patches of sea. Second, after all the rivers have been done, these small seas are turned into proper lakes. But a lot of the problems I've been having have been associated with the redirection of rivers into lakes. So it occurred to me: why not create those small areas of sea before any rivers have been placed at all? Moreover, what if, at that same stage, we alter the shape of the land for quite a way around to ensure that all the rivers naturally flow into that patch of sea, during the river calculation phase, without having to be artificially routed into it?

So I tried this. First, the program creates those small areas of sea after the precipitation has been calculated (so it knows to put them in dry areas) but before any rivers have been calculated. Then we have a new routine to create a depression around each one. It's pretty simple: it moves outwards from the lake in a series of concentric circles, each time checking to see whether the elevation of each cell in that ring is higher than a set amount. Any cell that is too high is lowered to that set amount. Each time the circle widens, the set amount is raised a little. The program goes outward from the sea, slowly raising the maximum elevation, until no cells need to be lowered, and then it stops. The effect is as if an enormous saucer were gently pressed into the land around the lake, creating a wide bowl-like depression in which any rivers will naturally run into the lake at the centre. And then, as before, once all the rivers are done our patches of sea are turned into salt lakes. However, they are made much lower in elevation than they were before, so they sit nicely at the bottom of their basins.

I found that making the basins this way tended to result in rather straight rivers running down them, so I added some variation in the heights as the basins are made - and then had it do the Planchon-Darboux algorithm yet again, to ensure that no new depressions were created within the basins (other than the one at the centre, of course, which we actually want).

This gets us global river maps like this:


You can see (hopefully) that some of those isolated lakes have got quite extensive systems of rivers draining into them, like spiders sitting in the middle of large webs.

However, this did cause some annoying problems (of course) at the regional level. Some rivers stopped just short of the lakes, like this:


I think that this was because, when creating the rivers at the global level, UW was unable to run these ones on for some cells into the sea, as it normally does, because the sea was so small. At the regional level, the rivers therefore stop when they reach (what was originally) the sea tile, but because the coastline of the lake doesn't map perfectly onto the boundary between tiles, it may not reach the actual lake. (This is just a guess. It may be caused by something else entirely. Who knows?)

I spent quite a lot of time trying to rectify this, either by tinkering with the global river calculation or by adding a routine at the regional level to detect these unfinished rivers and finish them. Eventually I went with a solution of the latter kind, but it's a real bodge job. It ought to detect the nearest lake or sea cell and create new river directly to it, but for some reason this just won't work. So now it just continues the river in the direction it was originally going in until it hits lake or sea. This isn't really ideal, because perhaps it wasn't going in a direction that would hit lake or sea (although you'd think it would usually be). Still, this bodge works for now, and perhaps I'll be able to see what's wrong with the superior method when I'm less tired.

So now I'm getting salt lakes like these (both relief and river maps, for clarity's sake):



I like this one, where a couple of the rivers flow through a rift lake and then subsequently drain into a salt lake:



There is another issue. Previously, we could guarantee that any endorheic lake would have at least one river flowing into it, because they were created on rivers during the river calculation phase. With this new method, the lakes are placed before any rivers have been done at all, so there's always a chance that no river will flow into the lake, even with the wide basin around it. Since it's being placed in a desert, this may be quite probable. That's not ideal. However, it's not much of a problem, thanks to the lake precipitation effect. If there is any prevailing wind over the lake, it will cause some precipitation to occur nearby, and that should result in at least some small rivers, which our nice basin will cause to flow back into the lake. Here's an example of a lake that's affecting the local climate:


And here's the river map, showing the rivers in that patch of milder climate:


I rather like this, as the lake has its own complete, self-contained hydrological system going on there.

Of course, if the lake is somewhere without any prevailing winds (such as the horse latitudes, which are associated with deserts after all), this precipitation effect won't occur and so these rivers won't form either. But that doesn't happen tremendously often, and I don't think it's a huge problem - after all, desert rivers are pretty unreliable. Perhaps endorheic lakes with no inflows at all are just on the verge of drying up.

Now all of this raises the question: what about freshwater lakes? Could I adapt this basin-carving method to those, so that they too have wide drainage areas with rivers flowing naturally into them, avoiding all the messing about with river redirection that they currently involve? It's not as straightforward as it might seem. This new method of doing the salt lakes involves placing them at a low elevation - lower than the surrounding terrain - and then carving that surrounding terrain into a saucerlike depression around the lakes. But freshwater lakes need to have outflows. That means they can't be lower than all of the surrounding terrain. They must, in fact, be at the elevation of the outflowing river, which itself must then drop in elevation as it moves away from the lake.

Suppose we try the following. After the precipitation calculations, but before the river calculations, we pick random spots that aren't in deserts (these will certainly have rivers running through them of some size or another). We then use a lake template to flatten an area around the starting spot, such that any cells that are higher are lowered to be the same elevation as the starting spot, but any cells that are lower are left alone. Because of Planchon-Darboux, every area on the map has at least a gentle slope, so that should effectively mean that our starting spot now has a flattened area cut into the hillside above it. Then we run our basin routine around this spot. This again will affect the area upslope of our starting point. Then we run Planchon-Darboux again (well, we're already running it after creating the endorheic basins, so we'll just do the freshwater basins before that point so it captures them too). This should result in the flattened area becoming a gentle slope. Now, when we do the river calculations, any rivers within the catchment area of the basin should hopefully run down into it, meet, and flow out naturally as a single river from the starting spot down the slope that was already there. Finally, we place our lake over the flattened area in the normal way.

That gets us lakes like this:


It hasn't really worked. The lake has multiple outflows and its catchment area doesn't seem to be very wide. If the original selected point was on only a relatively shallow slope, then the basin carving won't have had much effect, and there might be multiple lake cells that are low enough to have rivers flowing out of them.

So we need to tinker further with the routine. What if we change it so that the basin is carved not merely by lowering cells that are too high, but by also raising cells that are too low? In other words, we don't simply press a giant saucer down on the terrain - we build one up on top of it. That way, we can guarantee a wide catchment area and also avoid multiple outflows. But we still want one outflowing river: how will that escape from the lake? Simple: we create an array and mark on that array all the cells downstream of our starting lake cell. Then, when we create the basin, we avoid messing with any cells that are marked on that array. That should ensure a path for one - and only one - river to leave the lake.

Trying that, I get the following world map:


Looks like I need to add a line stopping the basins from appearing over the sea. Also, of course, the basins rise up gradually as they get further from the central lake - and then they stop, leaving a sharp cliff edge down, so we have these enormous disc-like structures all over the place, rather like Venusian pancake domes. And, last of all, there's something wrong with the slopes of the basins - they're not directing the rivers towards the lakes:


So that was pretty comprehensively wrong. Let's try correcting some of these problems. Instructing the program not to create basins over seas is easy. Getting the slopes to work properly is harder. I tried increasing the steepness of the slopes, but that didn't help:


The whole basin is getting raised more than it should - you can see that the land is uniformly high right up to the shores of the lakes. I think the problem is the depression-filling algorithm. Marking out the path of the outflowing river doesn't seem to be stopping the algorithm from filling the basin up as if it's an unwanted depression. I try making that path wider, but it doesn't help.

After some time, my stupidity becomes apparent. All of this is being done before the flow directions are calculated. But when I mark the cells downstream of the outflow, I'm relying on the flow directions. So that isn't working. So when the basins are created, they don't leave any route for an outflow at all. So the depression-filling routine just fills the basins up completely.

So! I write a new routine to mark the downstream cells that doesn't rely on pre-calculated flow directions, but works them out on the hop. Now we have lakes like this:


You can see the raised basin there quite clearly - the edges are still sharp, so I will need to do something about that. The river map of this region shows the lake's catchment area even more clearly:


But by some miracle it does seem to be working. All the rivers in that area are flowing straight into our lake, except for the one that's flowing out of it, to the north.

I find similar patterns around other lakes. However, some have more than one outflow, which shouldn't be happening. I wonder whether this is somehow caused by the variations in the basin-creating routine. I change it so that the basins are smooth, and move the freshwater lake basin routine to be after the depression-filling routine associated with the salt lake basins. This doesn't help much - I'm still getting lakes like this one (which admittedly looks pretty cool, but surely isn't realistic):


There are also issues like this:


Look at all those rivers running to the lake through the mountains. The basin is created in such a way that mountains are basically ignored (remember, rivers are calculated on the basis of the underlying elevation, not the mountains themselves), and so we get unrealistic results like that. There are also some strange and annoying artefacts here: the outflowing river from this lake has turned into an estuary all the way along, and there are some really odd sections of sea disconnected from the main ocean, near the coasts. I'm not sure why. Parts of the coastline itself look too straight and blocky. I think that this last issue is caused by the high ground of the basin being near the coast, which forces the diamond-square routine to create less variation when working out the coastlines.

My conclusion: trying to do freshwater lakes using the basins method is just more trouble than it's worth. The existing method does more or less work most of the time, so I'll stick with that, at least for now. Which means that the second half of this post was basically a waste of time... but at least I gave it a try!

No comments:

Post a Comment