Skip to content
Sample of Main Vein

complexification_net · mainVein

Main Vein

A single, meandering recursive vein grows from the center of a dark substrate. Offshoots branch off the main vein with smaller curvature amplitude and shorter lifetime, then terminate. Tarbell describes the piece as 'a meandering recursive construct that maintains a single vein of continual growth,' with offshoots tapering and terminating quickly. At any moment only one vein segment is 'active' — the main vein — which justifies the construction of a never-ending recursive path. Occasionally the main vein doubles back and reveals the brownian scope of its journey; a hard cap on concurrent limbs prevents the field from filling in.

Original: https://web.archive.org/web/20041223174832/http://www.levitated.net/daily/levMainVein.html

▶ 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
complexification_net
Source
complexification.net
Evolution
growth
Render
grid_painting
Complexity
medium
Agents
1
Year
2001
Author
j.tarbell

Math essence

The main vein integrates x_{t+1} = x_t + L·cos(theta_t), y_{t+1} = y_t + L·sin(theta_t), with theta_{t+1} = theta_t + A·sin(omega·t). At each step it spawns up to 3 offshoots with Bernoulli probability p; each offshoot runs the same dynamics for a finite life span with smaller amplitude. Stage progress is tracked so growth stops after max_stage steps regardless of vein position.

Parameters

Name Type Default Range Description
dim int 500 200–1000 Square canvas side length
max_segments int 240 30–1000 Cap on offshoot segments on stage
segment_length float 4 1–12 Length of a single segment in pixels
meander_amp float 0.5 0–2 Curvature amplitude of main vein
meander_freq_min float 0.005 0–0.5 Min meander angular speed
meander_freq_max float 0.04 0–0.5 Max meander angular speed
branch_prob float 0.03 0–0.2 Per-step branching probability
branch_life_min int 18 4–200 Min offshoot lifetime in segments
branch_life_max int 70 8–400 Max offshoot lifetime in segments
max_stage int 240 30–2000 Hard cap on main-vein segments
bg_color tuple 15,18,22 null–null Background RGB
vein_color tuple 180,200,220 null–null Vein RGB
seed int null 0–999999 RNG seed

Reference

First 60 lines of reference.py. Full source: library_external/complexification_net/mainVein/reference.py

from __future__ import annotations

from typing import ClassVar

import imageio.v2 as imageio
import numpy as np


class MainVein:
    family: ClassVar[str] = "complexification_net"
    sketch: ClassVar[str] = "mainVein"

    def __init__(
        self,
        dim: int = 500,
        max_segments: int = 240,
        segment_length: float = 4.0,
        meander_amp: float = 0.5,
        meander_freq_min: float = 0.005,
        meander_freq_max: float = 0.04,
        branch_prob: float = 0.03,
        branch_life_min: int = 18,
        branch_life_max: int = 70,
        max_stage: int = 240,
        bg_color: tuple[int, int, int] = (15, 18, 22),
        vein_color: tuple[int, int, int] = (180, 200, 220),
        seed: int | None = None,
    ) -> None:
        self.dim = dim
        self.max_segments = max_segments
        self.segment_length = segment_length
        self.meander_amp = meander_amp
        self.meander_freq_min = meander_freq_min
        self.meander_freq_max = meander_freq_max
        self.branch_prob = branch_prob
        self.branch_life_min = branch_life_min
        self.branch_life_max = branch_life_max
        self.max_stage = max_stage
        self.bg_color = np.array(bg_color, dtype=np.uint8)
        self.vein_color = np.array(vein_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._segments: list[dict] = []
        self._stage = 0
        self._main_vein: dict | None = None
        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)
        self._segments = []
        self._stage = 0
        cx = self.dim / 2.0
        cy = self.dim / 2.0
        angle = float(self.rng.uniform(0, 2 * np.pi))
        self._main_vein = self._make_segment(

Try running it locally

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

python library_external/complexification_net/mainVein/reference.py

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

More from complexification.net

See all complexification_net artworks →