generative_pioneers · nake_walk_sequence
Walk-through-Raster (Nake)
Frieder Nake's 1966 'Walk-through-Raster' program (Algol 60 on a Telefunken TR4, plotted on a ZUSE Graphomat Z64): a repertoire of six signs — empty, vshort, vlong, hshort, hlong, dot — is sampled into a Markov chain whose transition probabilities vary with chain position so that 'vertical strokes are high at the chain's middle, empties dominate at the ends'. The chain is then walked through the raster cell-by-cell in one of three modes (row, column, diagonal). The visual effect is a structured-yet-unpredictable field where a clear bar of verticals emerges from sparse ends — exactly Nake's published demonstration that 'think the image, don't make it'.
Original: https://dam.org/museum/wp-content/uploads/2021/05/FN_WalkThroughRaster.pdf
▶ Try the live demo (JS port) ▶ Run reference.py via Pyodide 10 formulas have instant JS ports. The Pyodide path runs the actual Python in your browser — first load is ~6 MB, then instant.
Math essence
Given a chain position t ∈ [0,1] we set the base distribution p(sign | t) with p_vert ∝ (1−|2t−1|) and p_horiz ∝ (0.4+0.6·(1−|2t−1|)), then bias toward the previous sign (vertical sticks to vertical) before sampling. Each chosen sign is rasterized into its cell at the (ci, ri) index produced by the chosen mapping mode.
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dim | int | 512 | 200–1200 | Square canvas side length |
cols | int | 28 | 6–80 | Raster columns |
rows | int | 36 | 6–80 | Raster rows |
transition_seed | int | 11 | 0–999999 | Seed for the sign chain RNG |
p_vertical_peak | float | 0.55 | 0–1 | Vertical sign probability at the chain middle |
p_horizontal_peak | float | 0.18 | 0–1 | Horizontal sign probability at the chain middle |
fade_alpha | float | 0.3 | 0–1 | Pigment fade toward bg |
bg_color | tuple | 245,240,230 | null–null | Background RGB |
ink_color | tuple | 15,15,25 | null–null | Default ink RGB |
accent_color | tuple | 200,60,50 | null–null | Rare accent ink RGB |
mapping_mode | str | row | null–null | Chain-to-cell mapping: row | column | diag |
seed | int | null | 0–999999 | RNG seed for outer noise |
Reference
First 60 lines of reference.py. Full source:
library_external/generative_pioneers/nake_walk_sequence/reference.py
from __future__ import annotations
from typing import ClassVar
import imageio.v2 as imageio
import numpy as np
class NakeWalkSequence:
family: ClassVar[str] = "generative_pioneers"
sketch: ClassVar[str] = "nake_walk_sequence"
def __init__(
self,
dim: int = 512,
cols: int = 28,
rows: int = 36,
transition_seed: int = 11,
p_vertical_peak: float = 0.55,
p_horizontal_peak: float = 0.18,
fade_alpha: float = 0.30,
bg_color: tuple[int, int, int] = (245, 240, 230),
ink_color: tuple[int, int, int] = (15, 15, 25),
accent_color: tuple[int, int, int] = (200, 60, 50),
mapping_mode: str = "row",
seed: int | None = None,
) -> None:
self.dim = dim
self.cols = cols
self.rows = rows
self.transition_seed = transition_seed
self.p_vertical_peak = p_vertical_peak
self.p_horizontal_peak = p_horizontal_peak
self.fade_alpha = fade_alpha
self.bg_color = np.array(bg_color, dtype=np.uint8)
self.ink_color = np.array(ink_color, dtype=np.uint8)
self.accent_color = np.array(accent_color, dtype=np.uint8)
self.mapping_mode = mapping_mode
self._seed = seed
self.rng = np.random.default_rng(seed)
self.canvas = np.full((dim, dim, 3), self.bg_color, dtype=np.uint8)
self.time = 0
self._dirty = True
def reset(self, seed: int | None = None) -> None:
if seed is not None:
self._seed = seed
self.rng = np.random.default_rng(self._seed)
self.canvas = np.full((self.dim, self.dim, 3), self.bg_color, dtype=np.uint8)
self.time = 0
self._dirty = True
def _transition_probs(self, position_t: float) -> dict:
center = 1.0 - abs(2.0 * position_t - 1.0)
p_vert = self.p_vertical_peak * center
p_horiz = self.p_horizontal_peak * (0.4 + 0.6 * center)
p_dot = 0.04
p_empty = max(0.05, 1.0 - p_vert - p_horiz - p_dot)
total = p_empty + p_vert + p_horiz + p_dot
return { Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library_external/generative_pioneers/nake_walk_sequence/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from generative pioneers
Interruptions (Molnár)
generative_pioneers · molnar_interruptions
Vera Molnár's 1968 'Interruptions' series: a regular grid of rectangle cells where each cell's four border edges are drawn independently, each with its own random probability of being omitted.
Line Arrangements (Mohr)
generative_pioneers · mohr_line_arrangement
Manfred Mohr's 1969 plotter 'Line Arrangements': a fixed grid of columns and rows, each carrying a small set of nearly-parallel lines whose exact positions are random within the cell, overlaid with a layer of 45° diagonals whose length, position and orientation are independently random.
Paint by Numbers (Haeberli)
generative_pioneers · haeberli_painterly
Paul Haeberli's 1990 SIGGRAPH 'Paint by Numbers' — the founding paper of stroke-based rendering.
Plotter Trajectories (Hébert)
generative_pioneers · hebert_plotter_trajectory
Jean-Pierre Hébert's plotter-trajectory idiom — parametric Lissajous-like curves drawn over multiple passes, each pass slightly phase-shifted, each segment modulated by the local velocity of the pen so that slow regions lay down heavier pigment and fast regions trace a ghost line.