growth_aggregation · boxFittingImg
Box Fitting Img
The classic box fitting algorithm (see Box Fitting) modified with an image substrate, allowing new boxes to draw color from an invisible background. The following images use tornado photography as a color substrate and approximately 2200 individually fitted boxes. The structure of the fitted box region is determined randomly using the order in which boxes appear. Those boxes that appear earlier have a greater chance of a larger size.
Original: https://complexification.net
▶ 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
Same non-overlapping expansion algorithm as boxFitting, but each box samples its color from a procedural 'sky' substrate image at its birth location. The result is a fitted-box mosaic where the substrate color is preserved only at fitted positions, surrounded by a white border.
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dimx | int | 510 | 200–1500 | Canvas width |
dim | int | 330 | 200–1500 | Canvas height |
dimborder | int | 10 | 0–60 | White border thickness |
maxnum | int | 2000 | 100–8000 | Maximum concurrent boxes |
initial_boxes | int | 5 | 1–16 | Boxes spawned on reset |
substrate_seed | int | null | 0–999999 | Seed for procedural sky substrate |
Reference
First 60 lines of reference.py. Full source:
library/boxFittingImg/reference.py
from __future__ import annotations
from dataclasses import dataclass, field
from typing import ClassVar
import imageio.v2 as imageio
import numpy as np
def _sky_substrate(width: int, height: int, seed: int) -> np.ndarray:
"""Procedural 'sky' substrate mimicking the tornado/sky photos Tarbell used."""
rng = np.random.default_rng(seed + 7919)
yy = np.linspace(0.0, 1.0, height, dtype=np.float32)[:, None]
xx = np.linspace(0.0, 1.0, width, dtype=np.float32)[None, :]
sky_top = np.array([25.0, 35.0, 70.0], dtype=np.float32)
sky_bot = np.array([180.0, 170.0, 160.0], dtype=np.float32)
grad = yy
base = sky_top[None, None, :] * (1.0 - grad[:, :, None]) + sky_bot[None, None, :] * grad[:, :, None]
radial = np.sqrt((xx - 0.5) ** 2 + (yy - 0.55) ** 2)
swirl = 0.5 + 0.5 * np.sin(50.0 * radial + 8.0 * np.arctan2(yy - 0.5, xx - 0.5))
perturb = (swirl[..., None] - 0.5) * np.array([40.0, 25.0, -10.0], dtype=np.float32)[None, None, :]
noise = rng.normal(0.0, 12.0, size=(height, width, 3)).astype(np.float32)
img = np.clip(base + perturb + noise, 0, 255).astype(np.uint8)
return img
@dataclass
class _Box:
x: int
y: int
d: int
color: np.ndarray
ok_to_draw: bool = False
chaste: bool = True
class BoxFittingImg:
family: ClassVar[str] = "growth_aggregation"
sketch: ClassVar[str] = "boxFittingImg"
def __init__(
self,
dimx: int = 510,
dim: int = 330,
dimborder: int = 10,
maxnum: int = 2000,
initial_boxes: int = 5,
bg_color: tuple[int, int, int] = (0, 0, 0),
seed: int | None = None,
substrate_seed: int | None = None,
) -> None:
self.dimx = dimx
self.dim = dim
self.dimborder = dimborder
self.maxnum = maxnum
self.initial_boxes = initial_boxes
self.bg_color = np.array(bg_color, dtype=np.uint8)
self._seed = seed
self.substrate_seed = substrate_seed
self.rng = np.random.default_rng(seed) Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library/boxFittingImg/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from core library
Binary Ring
particles_paths · binaryRing
A system of path tracing particles evolves continually from an initial creation.
Bit 10001
networks_fractals · bit10001
(no description available) — Bit 10001 is a 3D particle system of 10,001 mutually-interacting points rendered to 2D via a rotating perspective camera.
Box Fitting
growth_aggregation · boxFitting
Box Fitting (source code)
Bubble Chamber
physics_chamber · bubblechamber
The Bubble Chamber is a generative painting system of imaginary colliding particles.
Buddhabrot
networks_fractals · buddhabrot
(no description available) — Buddhabrot is the rendering of escape-time trajectories of the Mandelbrot iteration.
City Traveler (variation A)
physics_chamber · citytraveler
City Traveler — a field of cities laid out on a grid, connected by thousands of travellers moving between random nearby pairs along sin-arc paths.