Skip to content
Sample of Reynolds Boids (Separation / Alignment / Cohesion)

shiffman_pearson_textbook · boidsClassic

Reynolds Boids (Separation / Alignment / Cohesion)

Reynolds' classic boids flocking model. Each of N agents has position and velocity. On every tick three steering rules are computed for each boid relative to its local neighbours: (1) separation — steer away from neighbours inside sep_radius with magnitude inversely proportional to distance; (2) alignment — steer toward the average velocity of neighbours inside ali_radius; (3) cohesion — steer toward the centroid of neighbours inside coh_radius. Each rule produces a desired velocity; the steering force is desired minus current velocity, capped at max_force. Position updates wrap toroidally on the square canvas. Boids leave a fading trail plus a bright head dot.

Original: https://natureofcode.com/autonomous-agents/

▶ 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
shiffman_pearson_textbook
Source
shiffman · pearson
Evolution
flocking_agent_simulation
Render
trail_accumulation
Complexity
high
Agents
150
Year
1987
Author
Craig Reynolds (1987); Nature of Code (Shiffman, 2012) and Generative Art (Pearson, 2011) treatments

Math essence

Toroidal pairwise distances via diff - dim*round(diff/dim). Per boid: sep_desired = mean(diff/(d^2 + eps)) over sep-neighbours; ali_desired = mean(velocity) over ali-neighbours; coh_desired = centroid(positions) - position over coh-neighbours. steer = limit(desired - vel, max_force). vel += weighted_sum(steers); vel = limit(vel, max_speed); pos = (pos + vel) mod dim. Canvas blending: canvas[p] = (1 - alpha) * canvas[p] + alpha * ink.

Parameters

Name Type Default Range Description
dim int 480 200–1200 Square canvas side length (toroidal).
num_boids int 150 20–600 Population size; Reynolds' canonical demo used ~150.
perception_r float 50 5–200 Default perception radius used when ali/coh radii are None.
sep_radius float 24 2–200 Separation perception radius.
ali_radius float 50 5–300 Alignment perception radius.
coh_radius float 50 5–300 Cohesion perception radius.
sep_weight float 1.5 0–5 Separation weight in acceleration sum.
ali_weight float 1 0–5 Alignment weight in acceleration sum.
coh_weight float 1 0–5 Cohesion weight in acceleration sum.
max_speed float 3.5 0.5–12 Velocity clamp (pixels per tick).
max_force float 0.18 0.01–1 Steering force clamp per rule.
trail_alpha float 0.35 0.01–1 Trail blend opacity per segment.
bg_color tuple 20,24,36 —
ink_color tuple 200,220,255 —
head_color tuple 255,220,130 —
seed int null 0–999999

Reference

First 60 lines of reference.py. Full source: library_external/shiffman_pearson_textbook/boidsClassic/reference.py

from __future__ import annotations

from typing import ClassVar

import numpy as np


class BoidsClassic:
    """Reynolds boids flocking (separation, alignment, cohesion).

    Implements the three classic Reynolds 1987 steering rules on a population
    of N point-boids with position and velocity:

    - **separation**: steer away from neighbours within ``sep_radius``
      (weighted inversely with distance).
    - **alignment**: steer toward the average heading of neighbours within
      ``ali_radius``.
    - **cohesion**: steer toward the centroid of neighbours within
      ``coh_radius``.

    Each rule produces a *desired* velocity; the steering force is the
    difference between desired and current velocity, capped at ``max_force``.
    Acceleration is integrated with explicit Euler, velocities are clamped to
    ``max_speed``, and the canvas wraps toroidally. Boids draw a short fading
    trail of their previous positions. This is the canonical Nature of Code /
    Coding Train / Generative Art formulation.

    Parameters
    ----------
    dim : int
        Square canvas side length (torus topology).
    num_boids : int
        Population size. Default 150 per Reynolds' original.
    perception_r : float
        Default radius for cohesion and alignment; separation uses its own.
    sep_radius, ali_radius, coh_radius : float | None
        Per-rule radii (default to ``perception_r`` if None).
    sep_weight, ali_weight, coh_weight : float
        Mixing weights for the three steering rules.
    max_speed, max_force : float
        Velocity and steering clamps.
    trail_alpha : float
        Per-segment trail fade.
    """

    family: ClassVar[str] = "shiffman_pearson_textbook"
    sketch: ClassVar[str] = "boidsClassic"

    def __init__(
        self,
        dim: int = 480,
        num_boids: int = 150,
        perception_r: float = 50.0,
        sep_radius: float | None = 24.0,
        ali_radius: float | None = 50.0,
        coh_radius: float | None = 50.0,
        sep_weight: float = 1.5,
        ali_weight: float = 1.0,
        coh_weight: float = 1.0,
        max_speed: float = 3.5,

Try running it locally

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

python library_external/shiffman_pearson_textbook/boidsClassic/reference.py

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

More from shiffman · pearson

Sample of Genetic Algorithm (Evolve Toward Target String)

Genetic Algorithm (Evolve Toward Target String)

shiffman_pearson_textbook · geneticAlgorithmString

A textbook genetic algorithm that evolves a population of binary strings toward a target ASCII string (default 'HELLO WORLD!').

View →
Sample of Lindenmayer L-System (Textbook Formulation)

Lindenmayer L-System (Textbook Formulation)

shiffman_pearson_textbook · lindenmayerTextbook

Lindenmayer L-system string rewriting with a 2-D turtle interpreter, the canonical textbook formulation used in both Shiffman's Nature of Code Ch.

View →
Sample of Mandelbrot Set (Escape-Time Fractal)

Mandelbrot Set (Escape-Time Fractal)

shiffman_pearson_textbook · mandelbrotSet

The Mandelbrot set rendered by escape-time iteration of z = z^2 + c on a window of the complex plane.

View →
Sample of Perlin Noise Flow Field

Perlin Noise Flow Field

shiffman_pearson_textbook · perlinFlowField

A 2-D scalar field of Perlin gradient noise is sampled on a coarse grid; each cell is assigned a heading theta = 2*pi * n.

View →
Sample of Random Walk / Drunkard's Walk

Random Walk / Drunkard's Walk

shiffman_pearson_textbook · randomWalkDrunkard

Many random walkers each start at the canvas center and take a stochastic 2-D step every tick.

View →
Sample of Stochastic Recursive Fractal Tree

Stochastic Recursive Fractal Tree

shiffman_pearson_textbook · recursiveTree

Stack-based stochastic fractal tree from Shiffman's Nature of Code Ch.

View →

See all shiffman_pearson_textbook artworks →