~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/fractal-garden

ASCII fractals rendered in CI: each preset is a view, every check draws them all

0
0
main
38 lines · 1.2 KB Raw History
"""Escape-time fractals, drawn as text."""

import math


def escape(z, c, limit):
    for i in range(limit):
        if z.real * z.real + z.imag * z.imag > 4.0:
            return i
        z = z * z + c
    return limit


def render(preset, width=78, height=28):
    """The preset's view as lines of text, darker where it escapes later."""
    kind = preset.get("kind", "mandelbrot")
    cx, cy = preset["center"]
    span = preset["span"]
    limit = preset.get("iterations", 80)
    shades = preset["palette"]
    julia = complex(*preset["c"]) if kind == "julia" else None
    # Characters are about twice as tall as they are wide.
    sx = span / width
    sy = span * 2 / width
    rows = []
    for y in range(height):
        row = []
        for x in range(width):
            p = complex(cx + (x - width / 2) * sx, cy + (y - height / 2) * sy)
            n = escape(p, julia, limit) if julia is not None else escape(0j, p, limit)
            row.append(shades[-1] if n == limit else shade(shades, n, limit))
        rows.append("".join(row))
    return rows


def shade(shades, n, limit):
    # On a log scale: most points escape in the first few steps.
    return shades[int(math.log1p(n) / math.log1p(limit) * (len(shades) - 1))]