Wednesday, August 18, 2021

Finishing the sea floor


Mid-oceanic rifts, with their associated ridges, are a really prominent feature of underwater terrain. The most famous one is the Mid-Atlantic Ridge:

But it's not really a single, discrete feature - rather, it's part of a network of rifts of this kind that wrap around the whole world, where oceanic plates are pulling apart from each other.

If we think of these rifts as basically arising at the mid-points between continental shelves, it's not too difficult to trace their paths. I can adapt the method I used to find the midpoints between mountain ridges. First, we place seed points along the edges of the continental shelves. Then we identify all the points next to those points. Then all the points next to those points - and so on until there are no points left. On each turn, we simply note down, for each point visited, which turn it was that we met it on. The result is an approximate map of how far each point of the ocean is from the nearest continental shelf, which we can represent like this (the lighter they are, the further):


Something weird happened in the western ocean there. It's something to do with the point at which the western boundary of the map meets the eastern (remember, after all this, the map gets adjusted east/west so that the boundary falls in the middle of the ocean, so the artefact there reflects where that boundary was before the adjustment). I can't work out quite why this happens, but it doesn't really matter, as we shall see.

Now the mid-oceanic points are those where two neighbouring points are closest to two different shelf points that are sufficiently far apart from each other. We can pick these out like this:


Obviously these are much too regular-looking. But we can do something about this by adapting the methods I used to make interesting continental shapes. First, we make an imaginary grid with squares a few pixels wide. Then we go through each intersection on that grid. If it's close enough to one of the points identified on the map above, we mark it. That gives us a set of points on a grid. Each one gets assigned a unique number, and we also identify its neighbours on the grid. If we draw lines between neighbouring points, we get an effect pretty similar to the previous one (now I'm drawing these lines on the elevation map itself):


However, because these lines are based on a list of points with known neighbours, and are not simply being read off a 2D array, it's now easy to move those points about and get wigglier lines. As with the continental outlines, I apply two transformations to them. One is based on a fractal, which determines how far north/south and east/west each point is moved. That means that each point is moved a similar (though not identical) distance to its neighbours. Second, each point gets a random nudge all of its own. Together, these two transformations give us a much more realistic map of oceanic rifts:


That looks a lot better. The rifts come and go, depending on the distance to the nearest continental shelf, but this should be fine as we can easily make the ridges' height depend on that distance, so they will fade in and out. If we do that, and also make the ridges wider, we get this:


I think that looks pretty good at the global level. At last, we can see where the tectonic plates of the world must be, even though my method doesn't actually simulate them at all!

At the regional level, though, it's not quite as impressive:


The ridge is completely undetectable! It is there - it's just that because it covers such a large area, the slope is gradual enough that you can't really see it. Clicking on different parts of the regional map reveals the different depths, but the changes are just not dramatic enough to be noticeable on the relief map, or indeed on the elevation map either.

Well, we can help things by adding undersea mountains. Oceanic rifts have parallel lines of increasingly more minor ridges running alongside them. As we raise the land on the global map, we can note down the distance each cell is from the central rift. Cells that are the same distance from that central rift can have underwater mountain ranges connecting them. With a bit of tinkering to improve the directions of the lines, and the addition of extra mountain peaks scattered about to stop them looking too linear (and also to reflect the chaotic nature of this kind of terrain in real life), we get something like this (the central rift is just off to the left of this map):


It's also a straightforward matter to add the central rift itself, with a high density of additional peaks around it:


I noticed something curious in one area though:


Where have these lines come from that are crossing the ridges?? By a process of elimination, I work out that it's something to do with the routines that draw the ridges themselves (nothing to do with the central rift or the peaks around it, or the random peaks that are scattered among the ridges). My best guess is that it's something to do with the pseudo-random number generator, which is set to a different seed for each tile before making the ridges there. Each tile's seed is, in part, generated by its coordinates on the global map, as well as by other distinctive properties such as its rainfall or temperature. It must be that in this region, the seed numbers in each column are similar enough that they are producing similar random numbers for the peak heights, leading to the illusion of these lines. They are not perfectly vertical because the locations of all of the ridge peaks are warped slightly by a global-scale fractal, which pushes them by a varying amount across the map to reduce the appearance of a grid. 

I can't make this happen in the same way elsewhere - for one thing, it would only create lines running north-south or east-west. But I'd like to reproduce the effect, or something like it, as I think that, by chance, it looks fantastic.

To do this, we need to store some new information at the point of world generation. Each central ridge point needs to know the angle of the line that is roughly perpendicular to the ridge at that point. Now, lines of this kind do not, in fact, normally pass through the central ridge at exactly right angles:


So this is my solution. We make (yet another) global-level fractal. On the basis of this fractal, we assign an angle - between 0 and 360 degrees - to every point on the map, so we have a global map of gradually changing angles. (Note: this means that making this fractal is a little more complicated than usual, because the values have to be able to wrap - e.g. if we're trying to find the midpoint between 30 and 350, the answer is 10, not 190.)

At the ridge points, we take the average of (1) this fractal-based angle and (2) the angle of the line that would actually be perpendicular to the ridge at that point. We will then use this average as the angle of the lines that we will draw on the regional map at this point.

This method ensures that we keep the realistic effect of mostly roughly parallel lines that don't cross the ridge at exactly right angles, without allowing anything too crazy such as lines that cross the ridge at a very acute angle.

Now, at the regional level, we go through each tile that contains central ridge in turn. (We do this for a considerably larger area than is actually shown in the regional map, because there might be lines entering the regional map from ridges that are off-screen.) Then we just draw straight lines from those tiles in the appropriate directions. Some of these are raised ridges, while others remove any ridges they encounter. The length and exact direction get a random offset too.

It takes a fair bit of experimenting (as well as a lot more maths than I'm at all comfortable with) to get it looking reasonable, but I end up with maps like these:



And I think these look pretty nice. Sometimes these radiating spikes make more of a confused jumble, but that's OK - confused jumbles are what mid-oceanic ridges are all about, really.

Now comes the tricky bit. Oceanic rifts are also crossed by more substantial fault lines that actually break up and stagger the line of the rift itself:


These lines are transform faults in the sea bed, breaking up the ridge systems:


How do we implement these?

Well, on the global map, we choose some points on the rift network. For each point, we shuffle along the rift a little way in each direction, to identify a short length of rift. Now we can use the work we've already done in the last bit, when we identified the angle of those lines crossing the rift at every point. We use the angle of the line at the point mid-way along our section of rift, and basically just shift that whole section of rift, and all its associated ridges and other information, a random amount along the line indicated by that angle. And we do that repeatedly all over the map.

That gets us this:


I found that the lines slashing across the ridges looked rather ugly on the global map, so I have toned down the pseudo-3D shadows around them, which helps. On the regional map, the lines of the faults themselves aren't actually visible. Instead, these areas look like this:







It's probably not tremendously realistic, but it adds some pleasing chaos to parts of the rift system, so I'll leave it at that.

One more feature I want to add to the oceans, at least for now, is deep-sea trenches. These tend to appear on the edges of some oceanic plates, where they meet continental plates:


To simulate these, I'll just run along the edges of some of the continental shelves drawing blobs. Where the blobs cover ocean that isn't continental shelf, I'll drastically increase the ocean depth.

And that gives us this:

On the regional map, these areas look like this:




And I think that looks suitably profound and mysterious.

With that, I'll leave the sea floors for now. They're not tremendously detailed or accurate, but I'm aware that most people probably won't care too much about what's going on down there, so hopefully what we've got now should suffice to add a little bit of believability.

Next, some refinements to the UI, including the ability to customise colours and other elements of the appearance from within the program.

No comments:

Post a Comment