openprocessing_p5js · AttractorNetwork
Inverse-distance Attractor Network
A population of point-agents, each carrying a position and a velocity, mutually attracted by an inverse-distance force F = G / max(d, d_min)^alpha along the displacement vector. The resulting dynamics produce organic, filament-like network patterns — the canonical OpenProcessing 'attractor network' look.
Original: https://openprocessing.org/browse/?q=Maths&time=anytime&type=tags
▶ 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
For every ordered pair (i, j): d = p_j - p_i; F = G * d / max(|d|, d_min)^alpha. Sum over j, integrate explicit Euler with capped acceleration and speed, fade trails onto canvas.
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dim | int | 512 | 200–1200 | Square canvas side length. |
num_agents | int | 60 | 8–400 | Number of agents. |
gravity | float | 90 | 0–1000 | Force constant G. |
power | float | 2 | 0.5–4 | Inverse-distance exponent alpha. |
min_dist | float | 4 | 0.5–64 | Soft-core distance below which repulsion dominates. |
max_speed | float | 3.5 | 0.1–12 | Velocity clamp. |
max_force | float | 0.35 | 0.01–3 | Acceleration clamp. |
friction | float | 0.02 | 0–0.5 | Per-tick velocity damping. |
line_alpha | float | 0.18 | 0.01–0.6 | Trail opacity per stamp. |
bg_color | tuple | 12,12,22 | — | Background canvas color. |
ink_color | tuple | 240,220,180 | — | Trail ink color. |
seed | int | null | 0–999999 |
Reference
First 60 lines of reference.py. Full source:
library_external/openprocessing_p5js/AttractorNetwork/reference.py
from __future__ import annotations
from typing import ClassVar
import numpy as np
class AttractorNetwork:
"""Network of agents mutually attracted by an inverse-distance force.
This is the canonical *OpenProcessing* "attractor network" sketch family
(cf. <https://openprocessing.org/browse/?q=Maths&time=anytime&type=tags>;
"Eyes attractor" by Pierre Bail and similar agent-network sketches that
have been forked thousands of times). Each agent carries a position and a
velocity; on every tick we compute, for every ordered pair ``(i, j)``,
the displacement vector ``d = p_j - p_i`` and apply a force of magnitude
``G * m_i * m_j / max(|d|, eps)**alpha`` along the unit displacement.
Because the force law is symmetric, agents end up forming filaments: they
are pulled toward dense regions until they collide, at which point short-
range repulsion takes over. We cap both speed and acceleration, integrate
with explicit Euler, and let the trails fade onto a running canvas. A
small random kick on respawn keeps the network from collapsing into a
single point.
The system exhibits organic network / web / mycelium-like patterns — the
classic "attractor" look that defines the genre on OpenProcessing.
"""
family: ClassVar[str] = "openprocessing_p5js"
sketch: ClassVar[str] = "attractorNetwork"
def __init__(
self,
dim: int = 512,
num_agents: int = 60,
gravity: float = 90.0,
power: float = 2.0,
min_dist: float = 4.0,
max_speed: float = 3.5,
max_force: float = 0.35,
friction: float = 0.02,
line_alpha: float = 0.18,
bg_color: tuple[int, int, int] = (12, 12, 22),
ink_color: tuple[int, int, int] = (240, 220, 180),
seed: int | None = None,
) -> None:
self.dim = dim
self.num_agents = num_agents
self.gravity = gravity
self.power = power
self.min_dist = min_dist
self.max_speed = max_speed
self.max_force = max_force
self.friction = friction
self.line_alpha = line_alpha
self.bg_color = np.array(bg_color, dtype=np.float32)
self.ink_color = np.array(ink_color, dtype=np.float32)
self._seed = seed
self.reset() Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library_external/openprocessing_p5js/AttractorNetwork/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from openprocessing · p5.js
Additive Synthesis Waveform Visualisation
openprocessing_p5js · SoundWaveform
Visualisation of additive synthesis: y(t) = A * sum_{i=0..N-1} a_i * sin(2π f_i t + phi_i).
Kaleidoscope Mirror Mandala
openprocessing_p5js · KaleidoscopeMirror
Draws a single wandering line and reflects it across N rotational mirrors around the canvas centre.
Mathematical Rose (Rhodonea) Patterns
openprocessing_p5js · PolarCurves
Overlay of multiple rose (rhodonea) curves in the canonical polar form r = a * cos((n/d) * theta + phase), parametrised by the rational multiplier k = n/d.
Poincaré Disk Hyperbolic Tessellation
openprocessing_p5js · HyperbolicTiling
Escher-style regular hyperbolic tessellation in the Poincaré disk.
Tron Lightcycle Trails
openprocessing_p5js · TronLightcycle
Tron-style lightcycle trails.