patterns — erode

generator verdict no votes yet
source — auto/a010_erode.g60_erode
def g60_erode(rng):
    """ERODE — a full field is carved by drainage channels descending a noise
    elevation, each channel stepping to its steepest downhill lattice neighbour
    and cutting the cell it leaves at a strength that grows the longer the
    channel has run, so tributaries that merge cut deeper than lone streams and
    the field reads as high ground eaten back to bare rock along the runoff."""
    N = rng.choice([32, 40, 50])
    c = Canvas(N, "GLYPH", "glyph", "erode", tiles=False)
    NX, NY = c.cols, c.rows
    nz = Value2D(rng, res=rng.choice([3, 4, 5]))
    elev = [[nz((i + 0.5) / NX, (j + 0.5) / NY) for j in range(NY)] for i in range(NX)]

    material = [[1.0] * NY for _ in range(NX)]
    flow = [[0] * NY for _ in range(NX)]

    dirs8 = [(1, 0), (-1, 0), (0, 1), (0, -1), (1, 1), (-1, -1), (1, -1), (-1, 1)]
    n_sources = rng.randint(int(NX * NY * 0.05), int(NX * NY * 0.12))
    steps = rng.randint(int((NX + NY) * 0.8), (NX + NY) * 2)
    cut = rng.uniform(0.05, 0.11)
    grow = rng.uniform(0.01, 0.035)
    floor = rng.uniform(0.04, 0.12)

    for _ in range(n_sources):
        i, j = rng.randrange(NX), rng.randrange(NY)
        power = cut
        for _ in range(steps):
            flow[i][j] += 1
            material[i][j] = max(floor, material[i][j] - power)
            power += grow
            here = elev[i][j]
            best, bd = None, here
            for dx, dy in dirs8:
                ni, nj = i + dx, j + dy
                if 0 <= ni < NX and 0 <= nj < NY and elev[ni][nj] < bd:
                    bd = elev[ni][nj]
                    best = (ni, nj)
            if best is None:
                break
            i, j = best

    ramp_chars = ramp([".", ":", "-", "+", "x", "o", "#", "▒"])
    base_idx = rng.randint(5, 7)
    floor_idx = rng.randint(0, 1)
    span = base_idx - floor_idx
    for i in range(NX):
        for j in range(NY):
            t = clamp((material[i][j] - floor) / (1.0 - floor))
            k = floor_idx + int(round(t * span))
            c.glyph(i, j, ramp_chars[k])
    return c
erode-glyph-32-61d8
erode-glyph-32-61d8
erode-glyph-40-9ab8
erode-glyph-40-9ab8

generator