Skip to content
Sample of Computer-Aided Painting (Schwartz)

generative_pioneers_2 · lillian_schwartz

Computer-Aided Painting (Schwartz)

Lillian Schwartz, who worked at Bell Labs from 1968 to 2001 with Kenneth C. Knowlton on the BEFLIX and EXPLOR graphics languages, produced a series of computer-aided films and paintings through the early 1970s — *Enigma* (1972), *Googolplex* (1972), *Apotheosis* (1972), and *Affinities* (1972) — all of which took a synthesised noise field, thresholded it to a binary mask, applied a symmetry operation (usually 4-fold rotational, sometimes 8-fold or 2-fold with translation), and recoloured the result on a CRT phosphor palette before sending it to a 16 mm film recorder. The pipeline is the algorithm: noise → threshold → symmetry → palette. Schwartz's signature is the *chromatic shift* (a different palette index per rotated copy) that gives the layered, moiré look of *Enigma* and *Apotheosis*. This reference implements that exact pipeline using value-noise fBm, a hard threshold, an N-fold rotation, and a six-colour palette with optional chromatic shift.

Original: https://en.wikipedia.org/wiki/Lillian_Schwartz

▶ 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.

Family
generative_pioneers_2
Source
generative_pioneers_2
Evolution
symmetry_with_noise
Render
noise_threshold_palette
Complexity
medium
Agents
0
Year
1972
Author
Lillian Schwartz (with Kenneth C. Knowlton)

Math essence

Build fBm noise F : [0,1]² → [0,1] (octaves=3, persistence=0.55), normalise to zero-mean / unit-std, threshold at τ to obtain a binary mask M. For each rotation r ∈ {0, 1/K, 2/K, …, (K−1)/K × 2π}, place M_r = rot90(M, r) on a black canvas using palette index p(r) = (r + t·chromatic_shift)·K mod 6. The final image is the union (max) of the K layers.

Parameters

Name Type Default Range Description
dim int 512 200–1200 Square canvas side length
octaves int 3 1–8 fBm octaves (1 = pure value noise)
persistence float 0.55 0.1–0.95 fBm amplitude falloff per octave
threshold float 0.62 0–1 Noise threshold (higher = sparser mask)
symmetry int 4 1–16 Rotational symmetry order K (4 = Schwartz's *Enigma* default)
rotate_quarters int 1 0–3 Extra quarter-turn applied to the whole image
chromatic_shift float 0.06 0–1 Palette index shift per rotation layer (the *Enigma* moiré)
palette_warmth float 0.6 0–1 Brightness/saturation of the palette
bg_color tuple 12,8,18 null–null Background RGB
seed int null 0–999999 RNG seed

Reference

First 60 lines of reference.py. Full source: library_external/generative_pioneers_2/lillian_schwartz/reference.py

from __future__ import annotations

from typing import ClassVar

import imageio.v2 as imageio
import numpy as np


class LillianSchwartz:
    family: ClassVar[str] = "generative_pioneers_2"
    sketch: ClassVar[str] = "lillian_schwartz"

    def __init__(
        self,
        dim: int = 512,
        octaves: int = 3,
        persistence: float = 0.55,
        threshold: float = 0.62,
        symmetry: int = 4,
        rotate_quarters: int = 1,
        chromatic_shift: float = 0.06,
        palette_warmth: float = 0.6,
        bg_color: tuple[int, int, int] = (12, 8, 18),
        seed: int | None = None,
    ) -> None:
        self.dim = dim
        self.octaves = octaves
        self.persistence = persistence
        self.threshold = threshold
        self.symmetry = symmetry
        self.rotate_quarters = rotate_quarters % 4
        self.chromatic_shift = chromatic_shift
        self.palette_warmth = palette_warmth
        self.bg_color = np.array(bg_color, dtype=np.uint8)
        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 _value_noise(self, w: int, h: int, period: int) -> np.ndarray:
        rng = self.rng
        gx = max(2, w // period)
        gy = max(2, h // period)
        grid = rng.random((gy + 1, gx + 1)).astype(np.float32)
        ys = np.linspace(0, gy, h, endpoint=False)
        xs = np.linspace(0, gx, w, endpoint=False)
        y0 = np.floor(ys).astype(int)
        x0 = np.floor(xs).astype(int)
        y1 = np.clip(y0 + 1, 0, gy)
        x1 = np.clip(x0 + 1, 0, gx)
        fy = (ys - y0).astype(np.float32)

Try running it locally

The reference implementation is self-contained Python with numpy. Install the package and run:

python library_external/generative_pioneers_2/lillian_schwartz/reference.py

Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.

More from generative_pioneers_2

Sample of Hypertransformations (Molnár)

Hypertransformations (Molnár)

generative_pioneers_2 · molnar_hypertransformations

Vera Molnár's 'Hypertransformations' (1974-1976), executed on the IBM 360 with a CRT 2250 display and output on a Benson plotter.

View →
Sample of P-159 D (Mohr)

P-159 D (Mohr)

generative_pioneers_2 · mohr_p159d

Manfred Mohr's 'P-159 D' (1969, Vincennes) sits in the P-159 family that the artist developed from his earlier P-021 / P-036 line-arrangement programs.

View →
Sample of Raster Sequence (Nake)

Raster Sequence (Nake)

generative_pioneers_2 · nake_raster_sequence

Frieder Nake's 'Walk-through-Raster' / 'Raster Sequence' (1966) is the first non-stationary Markov chain in computer art history.

View →
Sample of Structure Computer (Cohen / AARON)

Structure Computer (Cohen / AARON)

generative_pioneers_2 · cohen_structure_computer

Harold Cohen's AARON, begun at UCSD in 1967-1973 and continuously developed until Cohen's death in 2016, is the longest-running art-making AI in history.

View →
Sample of Text Rain (Utterback & Achituv)

Text Rain (Utterback & Achituv)

generative_pioneers_2 · utterback_text_rain

Camille Utterback and Romy Achituv's 'Text Rain' (1999) is one of the canonical interactive installations of the late-1990s computer-vision era, and the piece that won them a US patent (US 6,928,313) in 2005.

View →
Sample of Wall Drawings (LeWitt)

Wall Drawings (LeWitt)

generative_pioneers_2 · sol_lewitt_wall_drawings

Sol LeWitt's wall drawings (1968-2007) are the canonical example of conceptual-art-as-algorithm: the work is the set of written instructions, and any number of draftspeople can execute them with different results that all satisfy the same rule.

View →

See all generative_pioneers_2 artworks →