nervous_system_hansmeyer · FloraformGrowth
Floraform Growth
A 2D port of Nervous System's Floraform generative jewelry system. Inspired by Mahadevan's work on differential growth in leaves and lilies, Floraform simulates a thin elastic surface whose edges grow faster than its interior; the imbalance produces ruffles, convolutions and fractal folds. Here we collapse the simulation into a vein-like growth on a flat substrate: from a central seed a handful of tendrils extend and stochastically branch, with each generation shrinking slightly (thinner, shorter, lower growth-rate) — yielding a fleshy floral skeleton that resembles the venation patterns embedded in actual Floraform pieces.
Original: https://n-e-r-v-o-u-s.com/blog/?p=6721
▶ 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
Each tendril integrates x_{t+1} = x_t + L·cos(theta_t + eta_t) where eta_t ~ N(0, sigma^2) is a bending noise; remaining length decreases by L each step. Once length falls below a threshold the tendril spawns 1-2 children whose initial budget shrinks geometrically with depth (growth_decay^depth). A hard cap on the branch population plus a growth-decay with depth keeps the figure bounded and fractal-like.
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dim | int | 600 | 200–1200 | Square canvas side length |
n_initial_branches | int | 6 | 1–24 | Number of tendrils spawned from the central seed |
init_length | float | 0.35 | 0.02–0.6 | Initial tendril length as a fraction of dim |
extension_step | float | 0.006 | 0.002–0.06 | Per-step extension length as a fraction of dim |
split_length | float | 0.12 | 0.01–0.4 | Branch-trigger threshold as a fraction of dim |
branch_prob | float | 0.25 | 0–0.7 | Probability of branching when length falls below threshold |
branch_jitter | float | 0.85 | 0.05–2.5 | Angular range (radians) for child tendrils |
bend_noise | float | 0.13 | 0–1.2 | Per-step angular jitter sigma (radians) |
growth_decay | float | 0.88 | 0.5–1 | Per-depth multiplier on child tendril extension rate |
max_branches | int | 4000 | 50–12000 | Hard cap on concurrent tendrils |
max_steps | int | 600 | 20–1500 | Number of simulation ticks |
bg_color | tuple | 10,14,18 | null–null | Background RGB |
vein_color | tuple | 190,220,240 | null–null | Primary tendril RGB |
accent_color | tuple | 255,170,110 | null–null | Odd-depth tendril RGB |
seed | int | null | 0–999999 | RNG seed |
Reference
First 60 lines of reference.py. Full source:
library_external/nervous_system_hansmeyer/FloraformGrowth/reference.py
from __future__ import annotations
from typing import ClassVar
import imageio.v2 as imageio
import numpy as np
class FloraformGrowth:
family: ClassVar[str] = "nervous_system_hansmeyer"
sketch: ClassVar[str] = "FloraformGrowth"
def __init__(
self,
dim: int = 600,
n_initial_branches: int = 6,
init_length: float = 0.35,
extension_step: float = 0.006,
split_length: float = 0.12,
split_curvature_min: float = 0.55,
branch_prob: float = 0.25,
branch_jitter: float = 0.85,
bend_noise: float = 0.13,
growth_decay: float = 0.88,
max_branches: int = 4000,
max_steps: int = 600,
bg_color: tuple[int, int, int] = (10, 14, 18),
vein_color: tuple[int, int, int] = (190, 220, 240),
accent_color: tuple[int, int, int] = (255, 170, 110),
seed: int | None = None,
) -> None:
self.dim = dim
self.n_initial_branches = n_initial_branches
self.init_length = init_length
self.extension_step = extension_step
self.split_length = split_length
self.split_curvature_min = split_curvature_min
self.branch_prob = branch_prob
self.branch_jitter = branch_jitter
self.bend_noise = bend_noise
self.growth_decay = growth_decay
self.max_branches = max_branches
self.max_steps = max_steps
self.bg_color = np.array(bg_color, dtype=np.uint8)
self.vein_color = np.array(vein_color, dtype=np.uint8)
self.accent_color = np.array(accent_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._branches: list[dict] = []
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 Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library_external/nervous_system_hansmeyer/FloraformGrowth/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from nervous system × hansmeyer
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.
Subdivided Columns
nervous_system_hansmeyer · HansmeyerSubdivision
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.
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.