OnyxFolio

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.