Generation of fault lines
How to get mountain chains for our map? Collision and torque of tectonic plates generate characteristic linear patterns. Perlin or fractal noise alone cannot generate such structures, so let's think in a procedure on top of it for obtaining some physical-like chains. My favorite is a procedure where the full tectonic dynamics are simulated (online soon) but let's work here on a simpler and cheaper alternative. I hope your algebra skills are tuned!
Let's start with defining the box where we will work and the central points of the plates. These points will divide the box in pieces, each of them representing a plate. We can use voronoi cells indeed. We also assign a velocity to each plate, that is, a vector with certain length and direction (it can be randomly generated). The idea is to somewhat mimic this.
According to relative velocities between neighboring plates we will have:
- Convergent boundary: when they collide. Mountains, some earthquakes and eventual volcanoes are expected.
- Divergent boundary: when they slide apart. Valleys or new seafloor are expected, and some volcanoes as well but earthquakes are not.
- Transform boundary: when they move tangentially. No mountains but earthquakes are expected.
What we need then is to obtain:
(A) For every of the boundaries in the box
(B) selecting one by one together with the couple of plates involved,
(C) obtain relative velocities of the plates
(D) and get the parallel and perpendicular components to the fault line.
When perpendicular components point each other (as in the example) we will deal with a convergent boundary, being the modulus of the component the intensity of the collision (to be used for defining the height of the mountains or the scale of the earthquakes). In the contrary case we will deal with a divergent boundary instead, and modulus will be used for the deep of the valley/sea. However, if the dominant component is the parallel one, then we deal with a transform boundary. You can see that in fact every boundary will have a component of transform and another of divergent/convergent.
For coherence in directions and signs, it is important to keep a global criteria on the perpendicular and parallel components. For instance, this is how I will define the unitary basis for every boundary:
Note that every parallel unit vector (blue) points following a hypothetical flow from left to right, and every perpendicular unit vector (red) is oriented in such a way that the vector for the third dimension would point to you following the right-hand rule. Easy, right? (Rewording it: if parallel unit vector points 3 o'clock, perpendicular unit vector points 12 o'clock.) This criteria will be quite relevant for next steps and actually simplifies the algorithm: Indeed, once I have defined these basis vectors, I just need to follow:
1) For every boundary, I got the relative velocity as a single vector defined as the difference between the velocity vector of the plate at the 'top' (the one that the red unit vector is pointing) and the velocity vector of the plate at the 'bottom' (the one that the red unit vector is not pointing).
2) I project the relative velocity into the basis of the boundary (remember, red a blue unit vectors) just by the dot product between the velocity and each of the unit vectors. Transform forces are always given by the dot product with the parallel unit vector (blue) and sign or direction (left or right) doesn't really matters. However:
- If the dot product with the perpendicular unit vector (red) is positive, we deal with a divergent boundary.
- If the dot product with the perpendicular unit vector (red) is negative, we deal with a convergent boundary.
I'm showing below the convergent boundaries in red and the divergent in blue following this method. Cool. With this information I know where to put mountains, where to put valleys, and the scale of it according to the value obtained from the dot products.
However, it would look a bit orthopedic... lets' introduce some noise to the lines: first, I keep fixed the vertices of the boundaries but introduce some distortion in the lines as show below. I do this in a discrete fashion: I fix the density number of points per boundary so they are composed by small segments.
For every of these segments, I define the unitary basis following the criteria defined before. I show them below for this example but with less density of points (for making it easy to see). Note that all red and blue arrows keep pointing coherently: blue vectors follow the boundary as a streamline and red vectors always point to the same plate along the same boundary.
Applying the same rule as before for every individual segment, we got something that looks somewhat less rigid. In the plot below, the width represents the strength of the tectonic forces and the color the divergent or convergent nature of the fault.
Combining convergent and transform faults we can create a map for earthquakes to mimic this:
Ok, with the data generated like this we can now create our mountains! Here you can use your favorite procedure. For instance, this is how it looks in a flat surface with some lorentzian-shaped mountains/valleys along the lines:
But it would look cooler if we include some background Perlin noise and erosion/deposition:
...or focusing in a region, with a bit of more detail defining the sea level, including some rivers and biomes according to the elevation:
That it. It's a simple method that can be improved in many way but can also save your day. Anyway, I'm moving land for a more sophisticated procedure, updates soon! (or late).