Questing · 2026-08-10 · Fluid Dynamics · Zero Dependencies

EDDY

Place vortices on a canvas. Watch two thousand tracer particles spiral, filament, and fold around them — the Lagrangian skeleton of an ideal fluid laid bare.

Open Eddy →

What Is Eddy?

Eddy is an interactive sandbox for 2D point vortex dynamics — the exact mathematical model of an ideal (inviscid, incompressible) fluid. Click to place positive vortices (amber) or negative vortices (teal). Two thousand massless tracer particles advect with the resulting velocity field, leaving fading trails that expose the Lagrangian structure of the flow: the spirals, the filaments, the regions of stretching, the islands of stability.

The four presets demonstrate the canonical behaviours of the N-vortex problem. A translating dipole (one positive, one negative) slides across the canvas at constant speed — the same mechanism that propels a smoke ring through still air. A corotating pair (two same-sign) circles its centroid indefinitely. An alternating triangle (three with mixed signs) exhibits genuine Hamiltonian chaos: nearby vortex configurations diverge exponentially. The Kármán street (two staggered rows) models the vortex wake shed by a bluff body moving through fluid.

Point Vortex Theory

In 2D ideal fluid mechanics, the velocity field of an incompressible, irrotational flow is uniquely determined by its singular vorticity sources — point vortices. Each vortex j at position (xj, yj) with circulation Γj induces a velocity at any other point (x, y) given exactly by the Biot-Savart law for 2D flow:

v_x(x,y) = −Γj/(2π) · (y − yj) / r²
v_y(x,y) = +Γj/(2π) · (x − xj) / r²

where  r² = (x−xj)² + (y−yj)²  (+ ε² for numerical regularisation)
and  1/(2π) arises from the 2D Green's function of the Laplacian.

Sign convention: Γ > 0 → counter-clockwise swirl; Γ < 0 → clockwise.

Each vortex moves under the velocity induced by all the others — never by itself (the self-velocity is zero by antisymmetry). The collection of vortex positions forms a finite-dimensional Hamiltonian system. The Hamiltonian — which is conserved under exact integration — is the interaction energy between vortex pairs:

H = −(1/4π) · Σ_{i<j} Γi · Γj · ln(rij)

Two same-sign vortices (Γi·Γj > 0): repel like-sign → orbit centroid.
Two opposite vortices (Γi·Γj < 0): attract opposite → translate as pair.
Angular momentum  L = Σ Γi·(xi²+yi²)  is also conserved (no boundaries).
Total circulation  C = Σ Γi  is trivially conserved (no source/sink).

Integrable vs. Chaotic

The N-vortex problem has a striking integrability threshold. For N = 1 a single vortex is stationary (nothing to push it). For N = 2 the conservation of H, L, and C provides enough constants of motion to uniquely determine the trajectory: same-sign pairs orbit, opposite pairs translate, both periodically. The motion is integrable — no chaos, no sensitivity to initial conditions.

For N ≥ 3 with mixed circulations, the system generally has more degrees of freedom than conserved quantities, and motion becomes non-integrable. Tiny differences in initial vortex positions grow exponentially — positive Lyapunov exponents, the hallmark of chaos. This is a Hamiltonian system with no dissipation, yet producing bounded, stochastic-looking trajectories. The tracer particles make this visible: near an integrable configuration (two same-sign vortices) tracers organise into clean bands; in chaotic regimes they fold into the fractal filamentary structures of a strange manifold.

N=1: stationary. One degree of freedom, trivially conserved.
N=2: integrable. Two constants (H, C) close the 4D phase space.
N=3: generally chaotic. Phase space is 6D; only H, C, and L reduce
     it to 3D — not enough for invariant tori in general.
N→∞: 2D turbulence. Inverse energy cascade; vortex merging statistics.

The Translating Dipole — Smoke Rings

The most striking behaviour of the two-vortex system is the translating dipole: one positive and one negative vortex of equal magnitude, separated by distance d, translate together at constant speed v = Γ/(2πd) perpendicular to their separation axis. Neither vortex moves on its own — each is carried by the velocity field of the other.

This is the two-dimensional analogue of a smoke ring. In 3D, a vortex ring (a donut-shaped filament of vorticity) propels itself by the same mechanism: the ring's own induced velocity field pushes it forward. The speed of a thin vortex ring in 3D is v = (Γ/4πR)·(ln(8R/a) − 1/4), where R is the ring radius and a the core radius — but the fundamental physics is identical to the 2D dipole. Dolphins exploiting vortex rings ejected from their flukes, the toroidal bubbles blown by beluga whales, the thermal columns rising from heated pavement: all driven by the same self-induced vortex propagation.

Dipole translation speed:  v = Γ / (2π d)
Corotating pair frequency: ω = Γ / (π d²)   (d = separation)
Corotating pair period:    T = 2π²d² / Γ

Eddy uses Γ = 22 000 px²/t, d ≈ 100 px for the pair preset:
  ω = 22000 / (π × 10000) ≈ 0.70 rad/t
  T ≈ 8.98 time-units = 8.98 / (5×0.008) ≈ 224 frames ≈ 3.7 s at 60 fps

Von Kármán Vortex Street

When a bluff body (a cylinder, a car, a flagpole) moves through fluid, it sheds vortices alternately from its top and bottom. These organise into two staggered rows of opposite-sign vortices — the von Kármán vortex street, named after Theodore von Kármán, who in 1911 proved that the only stable staggered configuration has a specific spacing ratio: the perpendicular row separation h to the along-row spacing a must satisfy h/a = (1/π)·arcsinh(1) ≈ 0.281. Any other ratio is unstable and the street breaks down into turbulence.

In Eddy's Kármán preset the spacing ratio is h/a = 70/105 ≈ 0.67 — deliberately off the Kármán stability condition, so the street begins to destabilise after a few seconds, forming beautiful folding structures as the rows lose coherence. The oscillating lift force that a Kármán street exerts is the reason suspension bridges must be designed against vortex-induced resonance (the Tacoma Narrows Bridge collapsed in 1940 from exactly this mechanism).

Where This Appears in Nature

Wingtip vortices    — trailing vortex pair behind aircraft. Airlines
                       fly offset in pairs to exploit the updraft from the
                       neighbour's trailing vortex (V-formation birds too).

Atmospheric cyclones — large-scale 2D vortices in Earth's thin atmosphere.
                       Point-vortex models predict merger, splitting, and
                       irregular orbits of tropical cyclone pairs (Fujiwhara effect).

2D turbulence        — in soap films, stratified ocean layers, and the
                       atmospheres of Jupiter and Saturn, energy injected at
                       small scales cascades UPWARD to large coherent vortices
                       (inverse energy cascade) — opposite to 3D turbulence.
                       The Great Red Spot is a 2D vortex stable for centuries.

Quantum fluids       — vortices in Bose-Einstein condensates and superfluid
                       helium-4 are literal point vortices: quantised circulation
                       Γ = h/m (Planck's constant / boson mass), no viscous core.
                       Their dynamics is exactly the N-vortex Hamiltonian.

Geophysics           — the von Kármán street sets the oscillation frequency of
                       flags, causes Aeolian tones in power lines, and drove
                       the Tacoma Narrows collapse (strouhal number St ≈ 0.2).

Implementation

Canvas:    500×500 px (HiDPI: scaled by devicePixelRatio, max 2×)
Vortices:  [{x, y, gamma}] array, up to ~20 interactively
Tracers:   2000 particles in Float32Array(2000) × 2 (tx, ty) + Int8Array (sign)

Vortex integration — 4th-order Runge-Kutta, 5 sub-steps per frame:
  DT = 0.008 time-units/step → 0.04 t/frame → ~25 t/s at 60 fps
  Self-velocity excluded (index exclusion in each k1–k4 evaluation)
  Vortices that leave ±120 px outside canvas are removed

Tracer advection — Euler, 1 step per frame (dt=0.04):
  vel(tx,ty) = Σ_j Γj·(−dy, +dx) / (TAU·(r²+EPS²))
  EPS² = 100 px²  (ε=10 px regularisation)
  Off-canvas tracers respawn uniformly inside canvas

Tracer colour — nearest vortex (Voronoi-like), updated every 8 frames:
  r < 230 px from a positive vortex → amber rgb(228,153,38)
  r < 230 px from a negative vortex → teal  rgb(38,183,162)
  no vortex within 230 px           → grey  rgb(152,140,116)

Rendering — phosphor-trail method:
  1. Fade canvas: rgba(7,7,13, 0.07) fill → trails persist ~14 frames
  2. Draw 3 tracer batches (one beginPath per colour, fills all at once)
  3. Redraw vortex markers fresh (no permanent trail on marker itself)
  Zero libraries, zero backend.

Built 2026-08-10 · Pure JavaScript · Canvas 2D · Zero backend · Live demo → · More questing →