Recursive Landscapes
Contents
The midpoint displacement algorithm is one of those beautiful ideas that is almost too simple. Take a line segment. Find its midpoint. Displace it vertically by a random amount. Repeat on each half. Keep going until you run out of resolution.
The result looks like a mountain range.
The Core Loop
def displace(points, roughness=0.5):
if len(points) < 2:
return points
result = []
for i in range(len(points) - 1):
result.append(points[i])
mid_x = (points[i][0] + points[i+1][0]) / 2
mid_y = (points[i][1] + points[i+1][1]) / 2
mid_y += random.gauss(0, roughness)
roughness *= 0.5 # each iteration is smoother
result.append((mid_x, mid_y))
result.append(points[-1])
return result
Fractal Dimension
The roughness decay factor controls how jagged the resulting terrain is. A value near 1.0 produces chaotic, nearly noise-like terrain. A value near 0.0 produces smooth hills. Real mountain ranges sit somewhere around 0.5.
This is not a coincidence — it reflects the actual fractal dimension of eroded terrain.
Extend to 2D
Apply the same algorithm to a grid of points with a diamond-square displacement rule to get full 3D terrain. The principle is identical; the indexing is considerably more annoying.