hodgin_iquilezles · MagnetoParticles
Magneto Particles (Hodgin Magnetosphere)
Particles pulled and pushed by N orbiting magnetic anchors whose charges flip sign over time. Each particle feels a Coulomb-like 1/r^2 force from every anchor plus a tangential drift that gives trajectories a magnetic-field-line curvature. Particles trace a hue-cycling low-alpha stroke, producing the looping ribbon-like patterns Hodgin used in the iTunes Magnetosphere visualizer.
Original: https://roberthodgin.com/project/magnetosphere
▶ 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 each particle i and anchor j, add F = k * sign(q_j) * (anchor_j - pos_i) / ((r_ij^2 + eps)^(3/2)). Add a tangential component t_ij = perpendicular(F_radial) * q_j * tangential_drift. Integrate velocity with global drag and clamp to max_speed, draw a segment from previous to new position with a colour computed from per-particle hue in [0,1).
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dim | int | 500 | 200–1000 | Square canvas side length in pixels. |
num | int | 1800 | 200–8000 | Number of particles. |
num_anchors | int | 6 | 1–16 | Number of magnetic anchor points orbiting the centre. |
anchor_strength | float | 180 | 20–600 | Force constant k in the Coulomb-like term. |
tangential_drift | float | 0.35 | 0–1.5 | Strength of the perpendicular-to-radial drift that curves trajectories. |
drag | float | 0.985 | 0.9–0.999 | Per-frame multiplicative damping of velocity. |
max_speed | float | 7 | 1–14 | Speed clamp (px/frame). |
trail_alpha | int | 32 | 4–96 | Stroke alpha (0-255). |
hue_jitter | float | 0.18 | 0–0.6 | Per-frame random hue drift applied to each particle. |
Reference
First 60 lines of reference.py. Full source:
library_external/hodgin_iquilezles/MagnetoParticles/reference.py
from __future__ import annotations
from typing import ClassVar
import numpy as np
class MagnetoParticles:
"""Magneto Particles — Robert Hodgin (flight404) *Magnetosphere* lineage, 2006.
Hodgin's *Magnetosphere* iTunes visualizer is a particle system in which
every particle carries a small charge and is pulled/pushed by a small
number of floating magnetic *anchors* whose charges oscillate over time.
Particles trace a curved, color-tagged trail, producing the iconic
looping magnetic-field-line look.
The formula here uses N point sources with per-source attractive or
repulsive Coulomb-like force ``F = k * sign(charge) * r̂ / (r^2 + ε)``,
adds a tangential drift for curvature, and accumulates a low-alpha
stroke buffer.
"""
family: ClassVar[str] = "hodgin_iquilezles"
sketch: ClassVar[str] = "magnetoparticles"
def __init__(
self,
dim: int = 500,
num: int = 1800,
num_anchors: int = 6,
anchor_strength: float = 180.0,
tangential_drift: float = 0.35,
drag: float = 0.985,
max_speed: float = 7.0,
trail_alpha: int = 32,
hue_jitter: float = 0.18,
ink_color: tuple[int, int, int] = (255, 255, 255),
background: tuple[int, int, int] = (6, 6, 12),
**_,
) -> None:
self.dim = dim
self.num = num
self.num_anchors = num_anchors
self.anchor_strength = anchor_strength
self.tangential_drift = tangential_drift
self.drag = drag
self.max_speed = max_speed
self.trail_alpha = trail_alpha
self.hue_jitter = hue_jitter
self.ink_color = np.array(ink_color, dtype=np.float32)
self.bg_color = np.array(background, dtype=np.float32)
self.reset()
def reset(self, seed: int | None = None) -> None:
self.rng = np.random.default_rng(seed)
self.x = self.rng.uniform(0, self.dim, size=self.num).astype(np.float32)
self.y = self.rng.uniform(0, self.dim, size=self.num).astype(np.float32)
a = self.rng.uniform(0, 2 * np.pi, size=self.num)
s = self.rng.uniform(0.0, 1.5, size=self.num)
self.vx = (s * np.cos(a)).astype(np.float32) Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library_external/hodgin_iquilezles/MagnetoParticles/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from hodgin × iquilezles
Boids Flock (Hodgin Murmuration)
hodgin_iquilezles · BoidsFlock
A 2D flock of boids steered by Craig Reynolds' three classic rules (separation, alignment, cohesion) over a coarse spatial-hash neighbor query.
Fractional Brownian Motion noise
hodgin_iquilezles · FBMNoise
Quilez's canonical fBM: a 2D value-noise base summed over N octaves whose frequency doubles and amplitude is multiplied by G = exp2(-H) per octave.
Mulberry32 PRNG (stratified scatter)
hodgin_iquilezles · Mulberry32RNG
Mulberry32 is a tiny 32-bit-state pseudo-random number generator popularised in the demoscene and used pervasively by Quilez and other graphics programmers as the RNG inside procedural sketches.
Saturn Rings (orbital resonance)
hodgin_iquilezles · SaturnRings
Thousands of particles are initialized in an annulus between inner_radius and outer_radius around a central mass, with circular orbital velocities v = sqrt(M/r).
Smooth-Minimum SDF field
hodgin_iquilezles · SmoothMinSDF
Two animated 2D SDF primitives (a moving circle and a translating slab) are blended with Quilez's quadratic-polynomial smooth-minimum and rendered as a scalar field.
Worley / Cellular Noise
hodgin_iquilezles · WorleyNoise
Quilez's classic 2D Worley noise: a unit grid of cells, each containing one pseudo-random feature point placed by a 2D integer hash.