Double Pendulum Mechanics
Rigorous classical mechanics simulation of coupled dual pendulums governed by Euler-Lagrange equations. Features real-time chaotic trajectory ribbon tracing, total mechanical energy tracking, and a live Phase Space (θ₁, dθ₁/dt) orbit inset.
60 FPS • Canvas 2D
Click + Drag to interact with field
</>
Full Executable Algorithm Code
167 lines
5972 chars
// 058 - Double Pendulum Mechanics (physics)
// 1:1 Original algorithm engine source
function createDoublePendulum() {
let th1 = Math.PI / 2;
let th2 = Math.PI / 2;
let w1 = 0;
let w2 = 0;
const g = 9.81;
const l1 = 120;
const l2 = 100;
const m1 = 1.5;
const m2 = 1;
const TRAIL_MAX = 450;
const trail = [];
const phaseSpace = [];
return {
setup() {
th1 = Math.PI / 2;
th2 = Math.PI / 2;
w1 = 0;
w2 = 0;
trail.length = 0;
phaseSpace.length = 0;
},
render(context, timeState, params) {
const { ctx, width, height } = context;
const subSteps = 10;
const dt = 0.02 / subSteps;
ctx.fillStyle = "rgba(2, 3, 7, 0.22)";
ctx.fillRect(0, 0, width, height);
const cx = width * 0.5;
const cy = height * 0.38;
const scale = Math.min(width, height) / 500;
const curL1 = l1 * scale;
const curL2 = l2 * scale;
for (let step = 0; step < subSteps; step++) {
const delta = th1 - th2;
const num1 = -g * (2 * m1 + m2) * Math.sin(th1) - m2 * g * Math.sin(th1 - 2 * th2) - 2 * Math.sin(delta) * m2 * (w2 * w2 * curL2 + w1 * w1 * curL1 * Math.cos(delta));
const den1 = curL1 * (2 * m1 + m2 - m2 * Math.cos(2 * th1 - 2 * th2));
const alpha1 = num1 / den1;
const num2 = 2 * Math.sin(delta) * (w1 * w1 * curL1 * (m1 + m2) + g * (m1 + m2) * Math.cos(th1) + w2 * w2 * curL2 * m2 * Math.cos(delta));
const den2 = curL2 * (2 * m1 + m2 - m2 * Math.cos(2 * th1 - 2 * th2));
const alpha2 = num2 / den2;
w1 += alpha1 * dt;
w2 += alpha2 * dt;
w1 *= 0.99995;
w2 *= 0.99995;
th1 += w1 * dt;
th2 += w2 * dt;
}
const x1 = cx + curL1 * Math.sin(th1);
const y1 = cy + curL1 * Math.cos(th1);
const x2 = x1 + curL2 * Math.sin(th2);
const y2 = y1 + curL2 * Math.cos(th2);
trail.push({ x: x2, y: y2, energy: Math.abs(w1) + Math.abs(w2) });
if (trail.length > TRAIL_MAX) trail.shift();
phaseSpace.push({ th1: th1 % (Math.PI * 2), w1 });
if (phaseSpace.length > 250) phaseSpace.shift();
ctx.save();
ctx.globalCompositeOperation = "screen";
if (trail.length > 2) {
ctx.beginPath();
for (let i = 0; i < trail.length; i++) {
const pt = trail[i];
if (i === 0) ctx.moveTo(pt.x, pt.y);
else ctx.lineTo(pt.x, pt.y);
}
ctx.strokeStyle = "#38bdf8";
ctx.lineWidth = 1.6;
ctx.stroke();
}
ctx.beginPath();
ctx.moveTo(cx, cy);
ctx.lineTo(x1, y1);
ctx.strokeStyle = "#64748b";
ctx.lineWidth = 3;
ctx.stroke();
ctx.fillStyle = "#0284c7";
ctx.beginPath();
ctx.arc(x1, y1, 8 * scale, 0, Math.PI * 2);
ctx.fill();
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.strokeStyle = "#94a3b8";
ctx.lineWidth = 2.4;
ctx.stroke();
ctx.fillStyle = "#38bdf8";
ctx.shadowColor = "#38bdf8";
ctx.shadowBlur = 14;
ctx.beginPath();
ctx.arc(x2, y2, 10 * scale, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0;
ctx.fillStyle = "#ffffff";
ctx.beginPath();
ctx.arc(cx, cy, 4, 0, Math.PI * 2);
ctx.fill();
const insetX = width - 150;
const insetY = height - 120;
const insetW = 130;
const insetH = 100;
ctx.restore();
ctx.save();
ctx.fillStyle = "rgba(15, 23, 42, 0.85)";
ctx.strokeStyle = "rgba(56, 189, 248, 0.3)";
ctx.lineWidth = 1;
ctx.strokeRect(insetX, insetY, insetW, insetH);
ctx.fillRect(insetX, insetY, insetW, insetH);
ctx.font = "9px monospace";
ctx.fillStyle = "#94a3b8";
ctx.fillText("Phase Space (\u03B8\u2081, \u03C9\u2081)", insetX + 8, insetY + 14);
if (phaseSpace.length > 2) {
ctx.beginPath();
for (let i = 0; i < phaseSpace.length; i++) {
const pt = phaseSpace[i];
const px = insetX + insetW * 0.5 + pt.th1 / Math.PI * (insetW * 0.38);
const py = insetY + insetH * 0.5 - pt.w1 * 5;
if (i === 0) ctx.moveTo(px, py);
else ctx.lineTo(px, py);
}
ctx.strokeStyle = "#f43f5e";
ctx.lineWidth = 1.2;
ctx.stroke();
}
ctx.font = "11px monospace";
ctx.fillStyle = "rgba(56, 189, 248, 0.9)";
ctx.fillText(`Double Pendulum \u2014 Lagrangian Mechanics`, 20, 28);
ctx.fillStyle = "#94a3b8";
ctx.fillText(`L = T - V = 1/2(m\u2081+m\u2082)l\u2081\xB2\u03B8\u0307\u2081\xB2 + 1/2m\u2082l\u2082\xB2\u03B8\u0307\u2082\xB2 + m\u2082l\u2081l\u2082\u03B8\u0307\u2081\u03B8\u0307\u2082cos(\u03B8\u2081-\u03B8\u2082) + (m\u2081+m\u2082)gl\u2081cos\u03B8\u2081 + m\u2082gl\u2082cos\u03B8\u2082`, 20, 44);
ctx.fillText(`\u03B8\u2081: ${(th1 % (Math.PI * 2)).toFixed(2)} rad | \u03B8\u2082: ${(th2 % (Math.PI * 2)).toFixed(2)} rad | Total E \u2248 Constant`, 20, 60);
ctx.restore();
}
};
}
// Default parameters from content metadata
const defaultParams = [
{
"key": "massRatio",
"label": "Mass Ratio (m₂/m₁)",
"type": "range",
"min": 0.2,
"max": 3,
"step": 0.1,
"defaultValue": 1,
"description": "Ratio of bob 2 mass to bob 1 mass"
}
];
if (!window.__art_instances) window.__art_instances = {};
if (!window.__art_instances['double-pendulum-chaos']) {
const inst = typeof createDoublePendulum === 'function' ? createDoublePendulum() : null;
if (inst && inst.setup) {
inst.setup({ ctx, width, height, dpr: 1, aspectRatio: width / height }, defaultParams);
}
window.__art_instances['double-pendulum-chaos'] = inst;
}
const instance = window.__art_instances['double-pendulum-chaos'];
if (instance && instance.render) {
instance.render(
{ ctx, width, height, dpr: 1, aspectRatio: width / height },
{ time, deltaTime: dt, frameCount: Math.floor(time * 60), fps: 60 },
defaultParams
);
} Edit in Interactive Playground
Zero Dependencies • Standalone Canvas 2D
ƒ
Mathematical Formulation
high
Analytical Equation
L=T−V,dtd(∂θ˙i∂L)−∂θi∂L=0
Click to expand
∑
Double Pendulum Mechanics
Full Mathematical System • physics
100%
Complete System of Equations
[Governing Law][Discrete Progression][Domain & Space][Parameter State]L=T−V,dtd(∂θ˙i∂L)−∂θi∂L=0alpha1=num1(th1,th2,w1,w2)/den1;alpha2=num2(th1,th2,w1,w2)/den2;x∈R2,t∈R+,ω∈[0,2π]λmassRatio=1(Mass Ratio (m₂/m₁))
L=T−V,dtd(∂θ˙i∂L)−∂θi∂L=0
Computational Implementation (JavaScript Engine Equivalent)
alpha1 = num1(th1,th2,w1,w2)/den1; alpha2 = num2(th1,th2,w1,w2)/den2; Compact Formula
alpha1 = num1(th1,th2,w1,w2)/den1; alpha2 = num2(th1,th2,w1,w2)/den2; Mathematical Tags
#classical-mechanics
#lagrangian
#double-pendulum
#phase-space
#physics-study
#chaos
Author: Classical Mechanics Core Target: 60 FPS
Press ESC or F to exit