Double pendulum · mistral-small-2603
Simulate a chaotic double pendulum on a canvas using the correct equations of motion, drawing the arms and a colorful fading trail of the tip.
transcript · 8 messages
Simulate a chaotic double pendulum on a canvas using the correct equations of motion, drawing the arms and a colorful fading trail of the tip.
thinking
The user wants me to create a chaotic double pendulum simulation with: 1. Correct equations of motion 2. Drawing on a canvas 3. Arms (two line segments) 4. Colorful fading trail of the tip I need to implement this as a single self-contained HTML file with inline CSS and JS, no external resources. Let me think about the physics: - A double pendulum consists of two rods and two bobs - The equations of motion are derived from Lagrangian mechanics - The state variables are the angles θ1 and θ2, and their angular velocities ω1 and ω2 - The equations involve complex trigonometric functions The standard equations for a double pendulum are: - Let m1, m2 be the masses - Let l1, l2 be the lengths - Let g be gravity - Let θ1, θ2 be the angles - Let ω1 = dθ1/dt, ω2 = dθ2/dt The equations of motion are: ``` d²θ1/dt² = (m2*l1*(ω1²*sin(θ1-θ2)*cos(θ1-θ2) + ω2²*sin(θ1-θ2) - (g/l1)*sin(θ1)*cos(θ1-θ2) - (g/l2)*sin(θ1-θ2)*cos(θ2)) / (m2 - m1*cos²(θ1-θ2)) d²θ2/dt² = ((m1+m2)*l1*ω1²*sin(θ1-θ2) + (m1+m2)*g*sin(θ1) - m2*l2*ω2²*sin(θ1-θ2)*cos(θ1-θ2) + m2*g*sin(θ2)*cos(θ1-θ2)) / (l2*(m1+m2*sin²(θ1-θ2))) ``` Actually, let me use the more standard form from literature. The equations can be written as a system of first-order ODEs: ``` dθ1/dt = ω1 dθ2/dt = ω2 dω1/dt = -(g*(2*m1 + m2)*sin(θ1) + m2*g*sin(θ1-2*θ2) + 2*sin(θ1-θ2)*m2*(ω2²*l2 + ω1²*l1*cos(θ1-θ2))) / (l1*(2*m1 + m2 - m2*cos(2*θ1-2*θ2))) dω2/dt = (2*sin(θ1-θ2)*(ω1²*l1*(m1+m2) + g*(m1+m2)*cos(θ1) + ω2²*l2*m2*cos(θ1-θ2))) / (l2*(2*m1 + m2 - m2*cos(2*θ1-2*θ2))) ``` I'll use a simpler version with equal masses and lengths for the simulation, which is common. Let me use: - m1 = m2 = 1 - l1 = l2 = 1 - g = 9.81 Then the equations simplify to: ``` dω1/dt = (-g*(2)*sin(θ1) - g*sin(θ1-2*θ2) - 2*sin(θ1-θ2)*(ω2² + ω1²*cos(θ1-θ2))) / (2 - cos(2*θ1-2*θ2)) dω2/dt = (2*sin(θ1-θ2)*(ω1²*cos(θ1-θ2) + g*cos(θ1) + ω2²)) / (2 - cos(2*θ1-2*θ2)) ``` I'll implement a 4th-order Runge-Kutta method to solve these ODEs numerically. For the visualization: - Canvas element with 2D context - Trail: store previous positions and draw them with decreasing opacity/color - Arms: draw two line segments from pivot to first bob, then to second bob - Colorful trail: use HSL color with changing hue based on time or position Let me create a complete HTML file with all this functionality.
I'll create a complete, self-contained double pendulum simulation with chaotic dynamics, colorful fading trail, and correct physics. Here's the full implementation:
/tmp/ws/index.html (8551 bytes)Successfully wrote 8551 bytes to /tmp/ws/index.html
thinking
The user wants a chaotic double pendulum simulation with correct physics equations, drawing arms and a colorful fading trail. I need to create a complete, self-contained HTML file with embedded CSS and JavaScript.
Let me think about the physics:
- Double pendulum has two rods with lengths l1, l2 and masses m1, m2
- State variables: theta1, theta2 (angles), omega1, omega2 (angular velocities)
- The equations of motion are nonlinear and lead to chaotic behavior
- I should use RK4 integration for accurate simulation
- Need to implement the correct equations of motion for a double pendulum
The equations of motion for a double pendulum are:
```
denom = (m1 + m2) * l1 - m2 * l1 * cos(theta1 - theta2)^2
alpha1 = [ (m1 + m2) * g * sin(theta1) - m2 * g * sin(theta1 - theta2) * cos(theta1 - theta2)
+ m2 * l2 * omega2^2 * sin(theta1 - theta2)
- 2 * m2 * l1 * omega1^2 * sin(theta1 - theta2) * cos(theta1 - theta2) ] / denom
alpha2 = [ (m1 + m2) * (g * sin(theta2) + l1 * omega1^2 * sin(theta1 - theta2) - g * sin(theta1) * cos(theta1 - theta2))
+ m2 * l2 * omega2^2 * sin(theta1 - theta2) * cos(theta1 - theta2) ] / denom
```
Where alpha1 and alpha2 are the angular accelerations (domega1/dt, domega2/dt).
I'll create:
1. A full HTML file with embedded CSS and JavaScript
2. Canvas setup with proper sizing
3. RK4 integration for accurate simulation
4. Correct physics equations for double pendulum
5. Colorful fading trail using HSLA colors
6. Interactive features: click to reset, space to pause
7. Visual elements: arms, bobs, pivot point
The implementation should be self-contained with no external dependencies.I'll create a complete, self-contained chaotic double pendulum simulation with correct physics and a colorful fading trail.
/tmp/ws/index.html (8580 bytes)Successfully wrote 8580 bytes to /tmp/ws/index.html
thinking
The user wants a chaotic double pendulum simulation with correct physics equations and a colorful fading trail. I need to create a complete, self-contained HTML file with: 1. Canvas for drawing 2. Correct equations of motion for a double pendulum 3. RK4 integration for accurate simulation 4. Colorful fading trail of the tip 5. Interactive controls (click to reset, space to pause) The double pendulum equations of motion are: - Two coupled second-order differential equations - Need to convert to first-order system for integration - Use RK4 method for accurate numerical integration - The equations involve sin(theta1), sin(theta2), sin(theta1-theta2), cos(theta1), cos(theta2), cos(theta1-theta2) Key implementation details: - State: [theta1, theta2, omega1, omega2] - Gravity g = 9.81 - Rod lengths l1, l2 - Masses m1, m2 - RK4 integration step - Trail array with fading colors using HSLA - Click to reset with random initial conditions - Space to pause/resume Let me write the complete HTML file with all this functionality.
I'll create a complete, self-contained chaotic double pendulum simulation with correct physics and a colorful fading trail. Here's the implementation:
/tmp/ws/index.html (8580 bytes)Successfully wrote 8580 bytes to /tmp/ws/index.html
thinking
The user wants a chaotic double pendulum simulation with: 1. Correct equations of motion 2. Drawing the arms 3. Colorful fading trail of the tip 4. All in one self-contained HTML file I need to create a complete, working simulation. Let me think about the physics: For a double pendulum, the equations of motion are derived from Lagrangian mechanics. The state variables are: - θ₁, θ₂: angles of the two rods from vertical - ω₁, ω₂: angular velocities The correct equations of motion are: ``` (m₁ + m₂)l₁θ₁'' + m₂l₂θ₂''cos(θ₁-θ₂) = -(m₁ + m₂)g sin(θ₁) + m₂l₂(θ₂')² sin(θ₁-θ₂) m₂l₂θ₂'' + m₂l₁θ₁''cos(θ₁-θ₂) = -m₂g sin(θ₂) - m₂l₁(θ₁')² sin(θ₁-θ₂) ``` This can be solved using numerical integration (RK4 is good for accuracy). Key features needed: 1. RK4 integration for accurate simulation 2. Canvas rendering with arms and bobs 3. Colorful fading trail (using HSLA with decreasing alpha) 4. Interactive controls (click to reset, space to pause) 5. Chaotic behavior (sensitive to initial conditions) Let me write a complete, self-contained HTML file with all CSS in a style tag and JS in a script tag. I'll use: - Canvas for rendering - RK4 integration for the physics - HSLA color model for the trail with hue cycling - Event listeners for interaction The implementation should be robust and work in any modern browser.
```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Chaotic Double Pendulum</title> <style> body { margin: 0; padding: 0; background: #000; display: flex; justify-content: center; align-items: center; height: 100vh; overflow: hidden; font-family: Arial, sans-serif; } #container { text-align: center; } #canvas { background: #000; border: 2px solid #333; box-shadow: 0 0 30px rgba(255, 255, 255, 0.1); } #info { color: #fff; margin-top: 20px; text-shadow: 0 0 5px rgba(255, 255, 255, 0.5); font-size: 16px; } h1 { color: #fff; font-size: 24px; margin-bottom: 10px; text-shadow: 0 0 10px rgba(255, 255, 255, 0.7); } </style> </head> <body> <div id="container"> <h1>Chaotic Double Pendulum</h1> <canvas id="canvas"></canvas> <div id="info">Click to reset | Space to pause</div> </div> <script> // Canvas setup const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); // Set canvas size function resizeCanvas() { const size = Math.min(window.innerWidth - 40, window.innerHeight - 100); canvas.width = size; canvas.height = size; centerX = canvas.width / 2; centerY = canvas.height / 2; scale = Math.min(canvas.width, canvas.height) * 0.4; } let centerX, centerY, scale; resizeCanvas(); window.addEventListener('resize', resizeCanvas); // Simulation parameters const g = 9.81; // gravity const l1 = 1.0; // length of first rod const l2 = 1.0; // length of second rod const m1 = 1.0; // mass of first bob const m2 = 1.0; // mass of second bob // State variables: [theta1, theta2, omega1, omega2] let state = [Math.PI/2, Math.PI/2, 0, 0]; // Trail parameters const maxTrailLength = 1000; let trail = []; let time = 0; let dt = 0.05; // time step let isPaused = false; // RK4 integration function rk4Step(state, dt) { function evaluate(y, t, h) { const [theta1, theta2, omega1, omega2] = y; // Precompute trigonometric values const sin1 = Math.sin(theta1); const sin2 = Math.sin(theta2); const sin12 = Math.sin(theta1 - theta2); const cos1 = Math.cos(theta1); const cos2 = Math.cos(theta2); const cos12 = Math.cos(theta1 - theta2); // Denominator for angular accelerations const denom = (m1 + m2) * l1 - m2 * l1 * cos12 * cos12; // Angular accelerations (domega1/dt, domega2/dt) const alpha1 = ((m1 + m2) * g * sin1 - m2 * g * sin12 * cos12 + m2 * l2 * omega2 * omega2 * sin12 - 2 * m2 * l1 * omega1 * omega1 * sin12 * cos12) / denom; const alpha2 = ((m1 + m2) * (g * sin2 + l1 * omega1 * omega1 * sin12 - g * sin1 * cos12) + m2 * l2 * omega2 * omega2 * sin12 * cos12) / denom; return [omega1, omega2, alpha1, alpha2]; } // Four stages of RK4 const k1 = evaluate(state, time, dt); const k2 = evaluate( state.map((val, i) => val + 0.5 * dt * k1[i]), time + 0.5 * dt, dt ); const k3 = evaluate( state.map((val, i) => val + 0.5 * dt * k2[i]), time + 0.5 * dt, dt ); const k4 = evaluate( state.map((val, i) => val + dt * k3[i]), time + dt, dt ); // Update state return state.map((val, i) => val + (dt / 6) * (k1[i] + 2 * k2[i] + 2 * k3[i] + k4[i]) ); } // Convert angles to Cartesian coordinates function getPosition(theta1, theta2) { const x1 = l1 * Math.sin(theta1); const y1 = l1 * Math.cos(theta1); const x2 = x1 + l2 * Math.sin(theta2); const y2 = y1 + l2 * Math.cos(theta2); return { x1, y1, x2, y2 }; } // Draw the pendulum function drawPendulum() { ctx.clearRect(0, 0, canvas.width, canvas.height); const { x1, y1, x2, y2 } = getPosition(state[0], state[1]); // Convert to canvas coordinates const px1 = centerX + x1 * scale; const py1 = centerY + y1 * scale; const px2 = centerX + x2 * scale; const py2 = centerY + y2 * scale; // Draw trail with fading colors if (trail.length > 0) { for (let i = 0; i < trail.length; i++) { const point = trail[i]; const alpha = i / trail.length; const hue = (time * 50 + i * 0.5) % 360; ctx.strokeStyle = `hsla(${hue}, 100%, 50%, ${alpha * 0.8})`; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(point.x, point.y); ctx.lineTo(px2, py2); ctx.stroke(); } } // Draw arms ctx.strokeStyle = 'rgba(255, 255, 255, 0.6)'; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(centerX, centerY); ctx.lineTo(px1, py1); ctx.stroke(); ctx.beginPath(); ctx.moveTo(px1, py1); ctx.lineTo(px2, py2); ctx.stroke(); // Draw bobs ctx.fillStyle = 'rgba(255, 0, 100, 0.8)'; ctx.beginPath(); ctx.arc(px1, py1, 12, 0, Math.PI * 2); ctx.fill(); ctx.fillStyle = 'rgba(0, 200, 255, 0.8)'; ctx.beginPath(); ctx.arc(px2, py2, 12, 0, Math.PI * 2); ctx.fill(); // Draw pivot ctx.fillStyle = 'rgba(255, 255, 255, 0.9)'; ctx.beginPath(); ctx.arc(centerX, centerY, 8, 0, Math.PI * 2); ctx.fill(); } // Update simulation function update() { if (!isPaused) { // Add current tip position to trail const { x2, y2 } = getPosition(state[0], state[1]); trail.push({ x: centerX + x2 * scale, y: centerY + y2 * scale }); // Limit trail length if (trail.length > maxTrailLength) { trail.shift(); } // Update state using RK4 state = rk4Step(state, dt); time += dt; } drawPendulum(); requestAnimationFrame(update); } // Event listeners canvas.addEventListener('click', () => { // Reset with random initial conditions state = [ Math.PI/2 + (Math.random() - 0.5) * 0.5, Math.PI/2 + (Math.random() - 0.5) * 0.5, (Math.random() - 0.5) * 2, (Math.random() - 0.5) * 2 ]; trail = []; time = 0; }); document.addEventListener('keydown', (e) => { if (e.code === 'Space') { isPaused = !isPaused; } }); // Start simulation update(); </script> </body> </html> ```
TAKE IT TO CODE
A single self-contained HTML file — copy it and open in any browser, or reuse the prompt with your own pi-agent run.
RUN
EVALUATION
Double pendulum simulates with colorful fading trails; click/drag/wheel reset it, but idle animation seems absent until interacted.
Vision grade · anthropic/claude-sonnet-5
MEASUREMENTS
Raw readings from the capture, not a verdict — the grade above is the only judgement. Percentages are how much of the screen changed; the measure under-reports sparse motion on a dark background.