Download

← Examples

mandelbrot

The Mandelbrot set, drawn in characters.

examples/mandelbrot in the repository.

module "main"

import "std/io"
import "std/string_builder"

WIDTH    :: 80
HEIGHT   :: 30
MAX_ITER :: 60

// Window onto the complex plane. The X-range is wider than the Y-range so a
// roughly 2:1 character cell renders the set close to its true aspect ratio.
X_MIN :: -2.0
X_MAX ::  1.0
Y_MIN :: -1.0
Y_MAX ::  1.0

// Density gradient from "outside" (escapes immediately) to "inside" (still
// bounded after MAX_ITER). 10 glyphs spanning the full iteration range.
PALETTE   :: " .:-=+*#%@"
PALETTE_N :: 10

// Iterate z := z² + c until |z|² > 4 (escape) or MAX_ITER. Returns the step
// count, capped at MAX_ITER for points still bounded.
iterations :: fn(cx: f64, cy: f64) -> i32 {
    zx := 0.0
    zy := 0.0
    for iter in 0..<MAX_ITER {
        zx2 :: zx * zx
        zy2 :: zy * zy
        if zx2 + zy2 > 4.0 {
            return iter
        }
        next_zx :: zx2 - zy2 + cx
        next_zy :: 2.0 * zx * zy + cy
        zx = next_zx
        zy = next_zy
    }
    return MAX_ITER
}

shade :: fn(iters: i32) -> char {
    idx :: (iters * (PALETTE_N - 1)) / MAX_ITER
    return PALETTE[i64(idx)]
}

main :: fn() -> i32 {
    dx :: (X_MAX - X_MIN) / f64(WIDTH)
    dy :: (Y_MAX - Y_MIN) / f64(HEIGHT)

    for py in 0..<HEIGHT {
        sb :: StringBuilder {}
        cy :: Y_MIN + f64(py) * dy
        for px in 0..<WIDTH {
            cx :: X_MIN + f64(px) * dx
            sb.append_char(iterations(cx, cy).shade())
        }
        println(sb)
    }
    return 0
}