Skip to main content

Playground · research instrument

Double Pendulum + Phase Space

Two rigid links, four state variables, and no randomness. Drag either bob, release it, and watch nearby initial conditions separate into chaos while the phase portrait paints the system’s hidden geometry.

Independent research instrument — not claimed as MakerPortal shipped product code. Methods, equations, assumptions, and limitations are disclosed so you can inspect what the page does and does not establish.

Deterministic chaos, live

Running. Drag either mass to choose new initial angles; the faint shadow starts just 0.006° away.

Configuration spaceDrag the bobs
Phase spaceθ versus angular velocity
θ₁ / ω₁
θ₂ / ω₂
Energy drift
Twin separation

Anatomy of the instrument

Every pixel above answers to the math below. Here is what each piece of the visualization, every control, and every readout is actually doing, and why it is built that way.

The two canvases

  1. 01

    Configuration-space canvas (left). Two massless rods of equal length, two point masses of equal mass, one frictionless pivot at the top. The colored bob (brand-red stroke) is the primary system. The faint blue ghost trailing behind it is the twin — identical except for 10410^{-4} rad of initial θ2\theta_2 offset. Both evolve from the same physics, same integrator. The fact that they visibly separate is not a rendering trick or a numerical artifact — it is deterministic chaos: two points arbitrarily close in phase space, driven apart exponentially by their own dynamics.

  2. 02

    Phase-space canvas (right). Horizontal axis is θ\theta, vertical axis is ω\omega. Each link paints one trace: link 1 in brand red, link 2 in anchor blue. The faint grid helps you read angular positions against the ±π\pm\pi range. The trail splits (issues a moveTo instead of lineTo) whenever the horizontal jump between successive points exceeds 45% of the canvas width — this preserves the true topology of the torus. Without the split you'd see a spurious line falsely claiming the pendulum teleported through θ=0\theta=0.

  3. 03

    Trail painting (trajectory history). Both canvases accumulate a polyline trail of the last 1800 points (physics frames). Points are sampled every 4th physics step to keep the trail buffer manageable without aliasing. The trail starts fully opaque and fades with age — newer points overwrite older ones — so you see the recent dynamic while the distant past recedes. "Clear paint" zeros both buffers.

  4. 04

    Drag interaction. You can drag either bob directly on the canvas to set initial angles. This bypasses the sliders — grab the mass circle, drag to the desired angle, release. The velocity is zeroed on release (restart from that angle), which is deliberate: you are setting an initial condition, not applying a continuous torque. Restart resets both angles to slider values.

The core ODE the canvas animates

x˙=f(x)=[ω1,  ω2,  α1(θ,ω),  α2(θ,ω)]\dot{\mathbf{x}} = \mathbf{f}(\mathbf{x}) = [\omega_1,\;\omega_2,\;\alpha_1(\boldsymbol{\theta},\boldsymbol{\omega}),\;\alpha_2(\boldsymbol{\theta},\boldsymbol{\omega})]^\top

Four first-order ODEs derived from the Euler–Lagrange equations. The accelerations α1,α2\alpha_1, \alpha_2 are the coupled expressions shown in the math section below, implemented line-for-line in acceleration(). No approximations, no small-angle linearization — this is the full nonlinear system.

Controls, readouts, and render loop

  1. 01

    Preset buttons. Four hand-picked starting configurations: Classic chaos (120°, −10°) — the workhorse, twin separates in seconds; Double flip (170°, 175°) — both near the unstable inverted equilibrium, slightest jitter triggers violent energy exchange; Calm orbit (25°, 40°) — low-energy KAM torus, twin stays locked; Asymmetric (92°, −128°) — mixed behavior, islands of order in a chaotic sea.

  2. 02

    Angle sliders (θ₁, θ₂). Set the initial angular displacement from the downward vertical — range ±180° with 0.5° resolution. The physics converts to radians internally. Changing either slider while running resets the simulation to those angles with zero velocity and clears the phase trails.

  3. 03

    Speed multiplier (0.25× to 2×). Controls how many physics steps are consumed per render frame. The physics time step is fixed at dt=1/240dt = 1/240 s — the multiplier does not alter the integrator, it only changes the ratio of simulation time to wall-clock time. At 1×, one second of real time ≈ one second of simulated time. At 2× the phase trails accumulate faster since more physics steps run per frame.

  4. 04

    Air damping slider (0 to 0.08). Adds a linear viscous damping term bωi-b\omega_i to each angular acceleration. At zero the system is Hamiltonian — energy conserved to RK4 precision. At nonzero values energy decays and the phase portrait spirals in toward (0,0)(0,0). The energy-drift readout changes to "dissipating" when damping is active, since the drift is no longer an error — it is the intended physics.

  5. 05

    The four readouts. θ₁/ω₁ & θ₂/ω₂ — live state of each link (angle in degrees, angular velocity in rad/s). Energy drift(EE0)/E0(E - E_0) / |E_0| as a percentage. E₀ is recorded on simulation start. With damping off this measures RK4's numerical dissipation (typically under 0.01% after 30 seconds for calm orbits). Twin separation — the L2L_2 angular distance between the primary and twin state vectors. In chaotic regimes this grows exponentially and saturates at π\sim\pi (fully uncorrelated). Displayed in exponential notation when it crosses into scientific-notation territory.

  6. 06

    The render loop. Uses requestAnimationFrame with a fixed-step accumulator. Each frame computes elapsed wall-clock time, multiplies by the speed multiplier, and drains the accumulator in dtdt-sized chunks (capped at 48 steps per frame). Physics runs at dt=1/240dt = 1/240 independent of display frame rate — the fixed step ensures deterministic, reproducible chaos. Trails are sampled every 4th physics step to decimate the draw load. Canvas rendering skips when the page is not visible (IntersectionObserver + visibilitychange). Cleanup on astro:before-swap cancels the frame, disconnects observers, and prevents memory leaks.

Gear behind this build

Nonlinear dynamics stack · 6 picks

Nonlinear dynamics6

More gear across every app: the full Gear list →

Essence

Two sticks. No randomness. Total unpredictability.

There is no dice in this machine. Same angles, same velocities, same future — every single time. That's what makes the double pendulum so unnerving: it's the purest example of deterministic chaos you can build on a kitchen table.

Two equal masses, two equal rods, one pivot. Four numbers completely describe it — θ1\theta_1, θ2\theta_2, ω1\omega_1, ω2\omega_2 — yet there is no closed-form formula for θ(t)\theta(t). Not because we haven't found one, but because none exists. Poincaré proved this in 1890 while wrestling with the three-body problem, and the double pendulum is its tabletop cousin.

The faint ghost trailing behind the colored bob is identical to the main system except for 10410^{-4} radians — about 0.006° — of initial offset on θ2\theta_2. Watch what happens. For a calm release they stay glued. For a chaotic one, they diverge until you can't tell they ever started together. That divergence is exponential, not gradual. It has a number — the Lyapunov exponent — and this simulation lets you see it live.

The intuition — why coupling breeds chaos

Think of a single pendulum: gravity provides a restoring torque proportional to sinθ\sin\theta. Simple, predictable, a cosine potential well. Now hang a second pendulum from the first.

Suddenly each bob feels two things it didn't before. The top bob is yanked by the inertia of the bottom bob — when m2m_2 swings, it tugs m1m_1 sideways through the rod. The bottom bob, meanwhile, lives in a non-inertial frame that is itself swinging. Its "gravity" is a combination of real gravity plus the centripetal and Coriolis accelerations of the first pivot.

The angle difference Δ=θ1θ2\Delta = \theta_1 - \theta_2 is the villain. Where a single pendulum has sinθ\sin\theta, the double has sinΔ\sin\Delta and cosΔ\cos\Delta multiplying velocity-squared terms. That ω2cosΔ\omega^2 \cos\Delta term is centrifugal — the faster the other arm spins, the harder it pulls. That coupling is nonlinear and it goes both ways:

  • ω22\omega_2^2 appears in ω˙1\dot\omega_1 — the bottom arm's spin forces the top.
  • ω12\omega_1^2 appears in ω˙2\dot\omega_2 — the top arm's spin forces the bottom.
  • Both are scaled by sin(θ1θ2)\sin(\theta_1-\theta_2) — strongest when the arms are perpendicular, zero when collinear.

In other words, the system feeds on its own motion. A tiny excess of speed in one arm gets converted — via that geometric sinΔ\sin\Delta gate — into a kick for the other. At low energy the gate stays almost closed and you get regular, quasi-periodic orbits. At high energy it swings wide open and the kicks cascade. That's the flip you see: one moment orderly, the next — tumbling.

Think of it like

Two ice skaters holding a rigid pole. The inner skater pivots around a point, the outer holds on. When the outer skater leans out (Δ90°\Delta \approx 90°), any spin whips the inner skater violently. When they line up (Δ0\Delta \approx 0), they can spin together smoothly. Chaos is what happens when that whip-crack keeps switching on and off.

Where chaos lives

Low energy: nested tori, near-integrable
Mid energy: mixed — islands of order in a chaotic sea
High energy: almost fully chaotic, ergodicity, frequent flips

You control this with θ1,θ2\theta_1, \theta_2. Both near 0 — calm. One near π\pi — inverted, tense, explosive. Preset “Double flip” parks both near the top, where the slightest jitter sends them over.

The math — from Lagrangian to code

1. Configuration and velocities

x1=L1sinθ1,y1=L1cosθ1x2=x1+L2sinθ2,y2=y1+L2cosθ2\begin{aligned} x_1 &= L_1 \sin\theta_1, & y_1 &= L_1 \cos\theta_1 \\ x_2 &= x_1 + L_2 \sin\theta_2, & y_2 &= y_1 + L_2 \cos\theta_2 \end{aligned}

We take yy positive down to match the canvas — physics is identical, just a sign flip in VV. Angles are from that downward vertical, so θ=0\theta=0 is hanging still.

2. Kinetic and potential energy

The Lagrangian is L=TVL = T - V. The kinetic part has three contributions — the top bob alone, the bottom bob alone, and the cross term where both move together:

T=12(m1+m2)L12ω12+12m2L22ω22+m2L1L2ω1ω2cos(θ1θ2)\begin{aligned} T &= \tfrac12 (m_1+m_2) L_1^2 \omega_1^2 + \tfrac12 m_2 L_2^2 \omega_2^2 \\ &\quad + m_2 L_1 L_2\, \omega_1\omega_2 \cos(\theta_1-\theta_2) \end{aligned}V=(m1+m2)gL1cosθ1m2gL2cosθ2V = -(m_1+m_2) g L_1 \cos\theta_1 - m_2 g L_2 \cos\theta_2

That middle cos(θ1θ2)\cos(\theta_1-\theta_2) is the entire story. Without it, you'd have two independent pendulums and a boring life. With it, the inertia matrix depends on configuration — the effective mass felt at one joint changes with the other joint's angle. This is what roboticists call a configuration-dependent mass matrix, and it's why inverse dynamics is hard.

3. Equations of motion that actually run

Apply ddtLωiLθi=0\frac{d}{dt}\frac{\partial L}{\partial \omega_i} - \frac{\partial L}{\partial \theta_i}=0. After a page of algebra you get the coupled accelerations the simulation integrates directly — this is the exact form in acceleration():

Let Δ=θ1θ2\Delta = \theta_1-\theta_2, D=2m1+m2m2cos2ΔD = 2m_1+m_2 - m_2\cos 2\Deltaα1=g(2m1+m2)sinθ1m2gsin(θ12θ2)2sinΔm2(ω22L2+ω12L1cosΔ)L1Dbω1α2=2sinΔ[ω12L1(m1+m2)+g(m1+m2)cosθ1+ω22L2m2cosΔ]L2Dbω2\begin{aligned} \alpha_1 &= \frac{-g(2m_1+m_2)\sin\theta_1 - m_2 g\sin(\theta_1-2\theta_2) -2\sin\Delta\,m_2(\omega_2^2 L_2 + \omega_1^2 L_1\cos\Delta)}{L_1 D} - b\omega_1 \\ \alpha_2 &= \frac{2\sin\Delta\,[\omega_1^2 L_1(m_1+m_2)+g(m_1+m_2)\cos\theta_1 + \omega_2^2 L_2 m_2\cos\Delta]}{L_2 D} - b\omega_2 \end{aligned}

bb is the optional air damping slider — zero by default, so the system is conservative and the energy diagnostic actually means something. Each α\alpha is ω˙\dot\omega. Note: denominators DD can never be zero for positive masses; D2m1D \ge 2m_1.

State vector

x=[θ1,θ2,ω1,ω2]T2×R2\mathbf{x} = [\theta_1,\theta_2,\omega_1,\omega_2]^\top \in \mathbb{T}^2 \times \mathbb{R}^2

The state lives on a torus cross a plane — angles wrap at ±π\pm\pi, velocities don't. That's why the phase-space trail splits instead of drawing a spurious line across the chart: we cut the wrap.

Total energy (the lie detector)

E=T(θ,ω)+V(θ)E = T(\boldsymbol{\theta},\boldsymbol{\omega}) + V(\boldsymbol{\theta})

With b=0b=0, EE should be constant. In the code we compute it every frame and show drift as (EE0)/E0(E-E_0)/|E_0| in percent. If you see 0.001% after a minute, that's RK4's numerical dissipation — not physics. Turn on damping and we intentionally let it decay, so the readout switches to “dissipating”.

Integrator — RK4, fixed step

f(x)=[ω1,ω2,α1,α2]k1=f(xn)k2=f(xn+dt2k1)k3=f(xn+dt2k2)k4=f(xn+dtk3)xn+1=xn+dt6(k1+2k2+2k3+k4)\begin{aligned} \mathbf{f}(\mathbf{x}) &= [\omega_1,\omega_2,\alpha_1,\alpha_2] \\ k_1 &= f(\mathbf{x}_n)\\ k_2 &= f(\mathbf{x}_n+\tfrac{dt}{2}k_1)\\ k_3 &= f(\mathbf{x}_n+\tfrac{dt}{2}k_2)\\ k_4 &= f(\mathbf{x}_n+dt\,k_3)\\ \mathbf{x}_{n+1}&=\mathbf{x}_n+\tfrac{dt}{6}(k_1+2k_2+2k_3+k_4) \end{aligned}

dt=1/240dt = 1/240 s, physics independent of display frame rate. Fixed step keeps chaos deterministic — adaptive stepping would add jitter that masks the true Lyapunov divergence. Accumulator + safety cap guarantees frame-rate independence.

Twin trajectory — measuring chaos

s(t)=wrap(x(t)x(t))s0eλts(t)=\bigl\|\operatorname{wrap}(\mathbf{x}(t)-\mathbf{x}'(t))\bigr\| \approx s_0 e^{\lambda t}

Shadow starts 10410^{-4} rad away on θ2\theta_2. s(t)s(t) live in the HUD is an L2L_2 angle distance. In chaotic regimes logs\log s vs tt is roughly linear — slope is finite-time Lyapunov exponent λ\lambda. When it saturates at π\sim\pi, orbits are uncorrelated.

Reading the phase portrait

The right canvas isn't decoration. Each trace is (θ,ω)(\theta, \omega) — position vs velocity. That's the natural language of dynamics. A single pendulum in this view traces a closed loop or, at high energy, a wavy line across the top. Area inside the loop is action. Shape tells you energy.

For the double pendulum you get two such traces, one per joint. When motion is regular — “Calm orbit” preset — you see neat nested loops, sometimes a thin torus projected as Lissajous-like figures. The system revisits almost the same (θ\theta, ω\omega) periodically.

When it's chaotic, loops smear into broad bands that fold and stretch. The folding is key: chaos isn't random scribble, it's deterministic stretching and folding — like taffy. Nearby points separate along one direction (positive Lyapunov) and converge along another (dissipation or, here, area-preserving shear). The banded texture you see painted over time is that process accumulating.

Why splits, not wrap lines:
Angles live on a circle. If θ\theta jumps from +179° to -179°, the shortest path on the circle is 2°, not 358°. Drawing a line across the chart would be a lie — it would claim the pendulum teleported through θ=0\theta=0. So the renderer cuts the segment whenever xn+1xn>0.45W|x_{n+1}-x_n| > 0.45W. You lose a pixel of ink and keep the topology honest.

How to spot

  • Regular: thin, crisp loops that retrace. Drift suggests energy error, not chaos.
  • Quasi-periodic: thickened loop — a torus cross-section, two incommensurate frequencies.
  • Chaotic: diffuse band, never closes, fills area. No amount of waiting makes it retrace.
  • Flip: sudden vertical jump in ω\omega as the arm goes over the top — kinetic spike from potential drop.

The hidden invariant (almost)

Dissipative pendulums have attractors. This one is Hamiltonian when b=0b=0 — volume in phase space is preserved (Liouville's theorem). Hence no attractor — chaotic orbits never settle, they just explore. The painted history is not approach to a fixed set, it's the trace of a single orbit that happens to be space-filling. Leave it running and it will eventually paint wherever energy allows.

Playbook — what to actually try

Start here

Classic chaos (120°, −10°). The workhorse. Watch the twin separation readout. It should sit around 10410^{-4}10310^{-3} for a few seconds, then explode — exponential, not linear. Clear paint, pause, restart to see it's reproducible.

Then break it

Drag the bobs. Pull the inner bob to ~170° — near inverted equilibrium. The potential VV is almost maximal there, an unstable fixed point. Release from rest. Now tiny hand jitter determines whether it falls left or right — the separatrix. The phase portrait will show a trajectory that hesitates, then a sudden high-ω\omega spike.

Double flip preset. Both arms near the top. They exchange energy violently: one arm can momentarily stop (ω0\omega \approx 0) as the other whips over. Watch kinetic energy slosh between joints — it's the cosΔ\cos\Delta cross term moving energy around.

Find order in chaos

Calm orbit (25°, 40°). Low total energy. Twin stays locked for hundreds of seconds — drift ~10810^{-8}% if damping off. This is KAM territory: Kolmogorov-Arnold-Moser theory says most low-energy tori survive weak nonlinearity. The phase loops are your visual KAM tori.

Add air damping. Slide to 0.02–0.04. Chaos dies. The attractor at (0,0,0,0) pulls everything down. The phase portrait spirals inward — now it's not Hamiltonian, volume contracts. Clear paint and compare decay rates: high-energy chaos takes longer to die because it keeps visiting high-ω|\omega| states where damping is stronger but intermittently stored as potential.

Tweaks that matter

Simulation speed

Physics dt stays 1/240 s — speed just steps more per render frame (up to 48 steps per frame with safety cap). At 2× you see longer-term mixing faster, but phase paint accumulates faster too. Slow to 0.25× to watch the whip transfer frame-by-frame.

Energy drift readout

With RK4 alone at this dt, drift after 30 s is typically < 0.01% for calm, < 0.2% for chaotic (higher velocities => more error). If you see > 1% you're either at extreme velocities or hitting floating-point limits. That's honest — no energy correction is applied to fake perfection.

Twin separation exponent

Log it mentally. If it doubles every ~2 s, λln2/20.35\lambda \approx \ln2/2 \approx 0.35 s1^{-1}. That means your ability to predict the state halves every 2 s — after 20 s, you'd need 10× more precise initial measurement to stay accurate. That's chaos quantified.

Where the math lives

Solver in this file — acceleration() + rk4(). Fixed-step, no allocations inside the loop. Trail painting is decoupled and sampled every 4 physics steps to keep 60 fps even on mobile. Angle wrapping uses branchless modulo: ((a+π)%2π +2π)%2π - π.

Honesty — what this is and isn't

What is real physics

The Lagrangian, the coupled accelerations, the exponential separation — all exact for ideal rigid, massless rods and point masses in vacuum. RK4 drift is bounded and shown, not hidden. The twin comparison isolates sensitivity to initial conditions from integration error because both twins share the same integrator.

What it simplifies

No rod mass or elasticity, no joint friction except the optional linear damping, no 3D — motion is planar. Collisions between bobs are ignored. RK4 is not symplectic, so long-term energy isn't bound like in Yoshida/Velocity-Verlet. For orbital-grade conservation you'd want symplectic; for visual chaos and interactive speed, RK4 wins.

Two gotchas that matter

RK4 is not symplectic

A symplectic integrator exactly conserves a perturbed Hamiltonian — energy stays bounded for exponentially long times. RK4 leaks energy, slowly and deterministically. After a minute of chaotic motion (high angular velocities, frequent flips), you may see 0.2% drift. That is not a bug — it is the integrator's honest numerical footprint. For a real orbital mechanics problem you'd use Verlet or a 4th-order Yoshida composition. For an interactive chaos demo at 240 Hz, RK4 gives far lower per-step error than 2nd-order symplectic methods. The energy readout shows the drift so you can judge for yourself.

Phase-space trail wrapping

Angles live on S1S^1 — a circle — not on R\mathbb{R}. When θ\theta jumps from +179° to −179°, the true separation is 2°, not 358°. But if you naively draw a line between those two x-coordinates on a linear canvas, you get a horizontal line spanning the entire chart — a false visual that claims the pendulum teleported through θ=0\theta=0. The fix: the renderer splits the trail (inserts a moveTo) whenever xn+1xn>0.45W|x_{n+1} - x_n| > 0.45W. You lose a fraction of a pixel of trail and keep the topology honest. This is the same issue that plagues every angle-valued time-series plot — wrapping isn't a bug, your coordinate chart is.

The solver, in JavaScript

The coupled acceleration function and the fixed-step RK4 stepper — these two functions drive every frame of both canvases. The angle-wrap utility is branchless for predictable performance.

RK4 + double-pendulum accelerations (JavaScript)

// Fixed-step RK4 for the double pendulum (from the page script)
function acceleration(θ1, θ2, ω1, ω2, b) {
  const Δ = θ1 - θ2;
  const = Math.sin(Δ),  = Math.cos(Δ);
  const D = 2 * MASS_1 + MASS_2 - MASS_2 * Math.cos(2 * Δ);
  const ω1_2 = ω1 * ω1, ω2_2 = ω2 * ω2;
  const g = GRAVITY;

  const α1 = (-g * (2 * MASS_1 + MASS_2) * Math.sin(θ1)
    - MASS_2 * g * Math.sin(θ1 - 2 * θ2)
    - 2 ** MASS_2 * (ω2_2 * LENGTH_2 + ω1_2 * LENGTH_1 * cΔ))
    / (LENGTH_1 * D) - b * ω1;

  const α2 = (2 ** (ω1_2 * LENGTH_1 * (MASS_1 + MASS_2)
    + g * (MASS_1 + MASS_2) * Math.cos(θ1)
    + ω2_2 * LENGTH_2 * MASS_2 * cΔ))
    / (LENGTH_2 * D) - b * ω2;

  return [α1, α2];
}

function rk4(state, dt, b) {
  const [θ1, θ2, ω1, ω2] = state;
  const deriv = (s) => {
    const [ω1_, ω2_, α1, α2] = [s[2], s[3], ...acceleration(s[0], s[1], s[2], s[3], b)];
    return [ω1_, ω2_, α1, α2];
  };
  const k1 = deriv(state);
  const k2 = deriv(state.map((v, i) => v + dt/2 * k1[i]));
  const k3 = deriv(state.map((v, i) => v + dt/2 * k2[i]));
  const k4 = deriv(state.map((v, i) => v + dt * k3[i]));
  return state.map((v, i) => v + dt/6 * (k1[i] + 2*k2[i] + 2*k3[i] + k4[i]));
}

// Branchless angle normalization to [-π, π]
const wrapAngle = a => ((a + Math.PI) % (2*Math.PI) + 2*Math.PI) % (2*Math.PI) - Math.PI;

Frequently asked questions

Why is the double pendulum chaotic when a single pendulum is not?

A single pendulum has two state variables (angle and angular velocity) — a 2D phase space. In 2D continuous-time systems, trajectories cannot cross, which prevents chaos (the Poincaré-Bendixson theorem). The double pendulum has four state variables — a 4D phase space. Trajectories can pass each other in the extra dimensions, enabling the stretching and folding that defines chaos.

Why use RK4 instead of a symplectic integrator?

A symplectic integrator (Verlet, Yoshida) exactly conserves a perturbed Hamiltonian and bounds energy error for exponentially long times. RK4 does not — it leaks energy gradually. But RK4 is 4th-order accurate at the time step, while explicit symplectic methods are typically 2nd-order. For the short integration times and visual purposes here (seconds to minutes of simulated time), RK4's lower per-step error outweighs the long-term drift concern. The energy-drift readout confirms typical drift is under 0.01% after 30 seconds.

What does the twin (ghost) trajectory show?

The faint blue pendulum starts from the exact same state as the main one except for a 10⁻⁴ radian offset on θ₂ (~0.006°). The separation between them grows exponentially in chaotic regimes — this is the signature of a positive Lyapunov exponent. When the twin diverges visibly, it means you cannot predict the pendulum's state more than a few seconds into the future without absurdly precise initial measurements.

Why does the phase portrait trail split instead of wrapping across the chart?

Angles live on a circle — +179° and −179° are 2° apart, not 358°. Drawing a line all the way across the chart would falsely imply the pendulum teleported through θ=0. The renderer cuts the trail whenever the horizontal jump exceeds 45% of the canvas width, respecting the actual topology of the torus-shaped state space.

Can I build a real double pendulum that behaves like this?

Yes — two rods connected by low-friction bearings approximates this model very well for the first few minutes. Real-world differences: rod mass and elasticity add higher-frequency modes, joint friction drains energy faster than the linear damping slider, and 3D motion (twisting out of plane) becomes significant at high energies. The qualitative behavior — exponential separation, energy sloshing, flipping — is identical.

Shareable still

The instrument, captured—not illustrated.

This 16:9 frame is rendered from the real browser instrument above. It is the page's canonical preview for image search, link unfurls, and posts that need to show what the tool actually does.

Download 1280 × 720 JPEG
Double Pendulum + Phase Space — live MakerPortal instrument screenshot
Canonical capture · real UI · no generated scientific artwork