nervous_system_hansmeyer · HansmeyerSubdivision
Subdivided Columns
Michael Hansmeyer's 2014 'Subdivided Columns' is a computational-design exercise in baroque complexity from algorithmic simplicity: start with a regular polygon, subdivide each edge, perturb each new vertex by a small random offset, repeat. After 8-16 iterations the smooth hexagonal (or octagonal, or square) silhouette has been replaced by a fibrous, coral-like fold structure whose topology is regular but whose surface ruffles like an ice-cream cone or a sea-fan. The piece is famous as an early showcase of algorithmic ornament — a single local rule, applied at scale, producing a global aesthetic that resists hand-authoring. This implementation works in 2D for tractable rendering (Hansmeyer's columns are extruded 3D), keeps every subdivision iteration as a coloured edge layer (cool edge_color for outer coarse folds, warm depth_color for inner fine detail), and uses semi-transparent stroke blending so dense overlaps naturally darken rather than overwrite — producing the painterly accretion that distinguishes a subdivided-column render from a CAD wireframe.
Original: https://www.hansmeyer.com/subdividedcolumns
▶ 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
Polygon P_0 has n_sides vertices on a circle of radius R. At each subdivision k in [0, K), each edge (a, b) is replaced by (edges_per_subdivision + 2) vertices: a, the p interior midpoints perturbed by normal-direction noise, and b. Perturbation magnitude decays as decay^k so coarse structure stays coarse. After K iterations the polygon has n_sides * (edges_per_subdivision + 2)^K vertices. Each edge of each subdivision is rendered as a vectorized line with alpha-blended color: color(depth) = (1 - 0.6 * (depth/max_depth)^0.8) * edge_color + 0.6 * (depth/max_depth)^0.8 * depth_color. The blend is associative so densely-overlapped regions accumulate toward the warm depth palette.
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dim | int | 600 | 200–1400 | Square canvas side length |
n_sides | int | 6 | 3–16 | Initial polygon side count |
subdivisions | int | 9 | 2–16 | Number of subdivision iterations |
edges_per_subdivision | int | 1 | 1–6 | Number of interior perturbed vertices inserted per edge (>=1) |
perturbation | float | 0.16 | 0–0.5 | Base perturbation magnitude as a fraction of dim |
perturbation_decay | float | 0.78 | 0.3–1 | Per-step magnitude decay (1=no decay) |
radius | float | 0.36 | 0.1–0.5 | Initial polygon radius as fraction of dim |
edge_color | tuple | 200,215,240 | null–null | Outer / coarse-fold RGB |
depth_color | tuple | 255,170,120 | null–null | Inner / fine-detail RGB |
bg_color | tuple | 6,8,14 | null–null | Background RGB |
edge_thickness | int | 1 | 1–3 | Stroke thickness in pixels |
edge_alpha | float | 0.25 | 0.05–1 | Per-stroke alpha (lower = softer accumulation) |
start_angle | float | 0 | -3.1416–3.1416 | Initial polygon rotation (radians) |
seed | int | null | 0–999999 | RNG seed |
Reference
First 60 lines of reference.py. Full source:
library_external/nervous_system_hansmeyer/HansmeyerSubdivision/reference.py
from __future__ import annotations
from typing import ClassVar
import imageio.v2 as imageio
import numpy as np
class HansmeyerSubdivision:
family: ClassVar[str] = "nervous_system_hansmeyer"
sketch: ClassVar[str] = "HansmeyerSubdivision"
def __init__(
self,
dim: int = 600,
n_sides: int = 6,
subdivisions: int = 9,
edges_per_subdivision: int = 1,
perturbation: float = 0.16,
perturbation_decay: float = 0.78,
radius: float = 0.36,
edge_color: tuple[int, int, int] = (200, 215, 240),
depth_color: tuple[int, int, int] = (255, 170, 120),
bg_color: tuple[int, int, int] = (6, 8, 14),
edge_thickness: int = 1,
edge_alpha: float = 0.25,
start_angle: float = 0.0,
seed: int | None = None,
) -> None:
self.dim = dim
self.n_sides = n_sides
self.subdivisions = subdivisions
self.edges_per_subdivision = edges_per_subdivision
self.perturbation = perturbation
self.perturbation_decay = perturbation_decay
self.radius = radius
self.edge_color = np.array(edge_color, dtype=np.uint8)
self.depth_color = np.array(depth_color, dtype=np.uint8)
self.bg_color = np.array(bg_color, dtype=np.uint8)
self.edge_thickness = edge_thickness
self.edge_alpha = edge_alpha
self.start_angle = start_angle
self._seed = seed
self.rng = np.random.default_rng(seed)
self.canvas = np.full((dim, dim, 3), self.bg_color, dtype=np.uint8)
self._edges: list[tuple[tuple[float, float], tuple[float, float], int]] = []
self._stage = 0
self.time = 0
self.reset()
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)
cx = self.dim / 2.0
cy = self.dim / 2.0
R = self.radius * self.dim
angles = self.start_angle + 2.0 * np.pi * np.arange(self.n_sides) / self.n_sides
polygon: list[tuple[float, float]] = [ Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library_external/nervous_system_hansmeyer/HansmeyerSubdivision/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from nervous system × hansmeyer
Floraform Growth
nervous_system_hansmeyer · FloraformGrowth
A 2D port of Nervous System's Floraform generative jewelry system.
Hyphae Network
nervous_system_hansmeyer · HyphaeNetwork
A 2D port of Nervous System's Hyphae generative jewelry.
Radiolarian Lattice
nervous_system_hansmeyer · RadiolarianLattice
Nervous System's Radiolaria series translates Ernst Haeckel's 19th-century radiolarian drawings into 3D-printed sculpture.
Voxel Field Cross-Section
nervous_system_hansmeyer · DillenburgerVoxelField
Benjamin Dillenburger's voxel-printing research (Digital Building Technologies, ETH Zurich, ~2016) replaced the smooth isosurface extraction of conventional architectural geometry with a literal 3D voxel grid: every cell is either solid or empty, and the boundary of the field is what gets fabricated.