oneshotlm
Compare all models on this prompt →

Double pendulum · qwen-2.5-72b-instruct

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.

⛨ sandboxed Open in new tab ↗
transcript · 8 messages
user

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.

assistant
assistant

To create a single-page web app that simulates a chaotic double pendulum, we will need to include HTML, CSS, and JavaScript in a single `index.html` file. The simulation will use the equations of motion for a double pendulum and draw the arms and a colorful fading trail of the tip on a canvas. Let's start by writing the file: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Double Pendulum Simulation</title> <style> body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background-color: #000; } canvas { border: 1px solid #fff; } </style> </head> <body> <canvas id="pendulumCanvas"></canvas> <script> const canvas = document.getElementById('pendulumCanvas'); const ctx = canvas.getContext('2d'); const width = canvas.width = window.innerWidth; const height = canvas.height = window.innerHeight; const L1 = 200; // length of first pendulum arm const L2 = 200; // length of second pendulum arm const m1 = 1; // mass of first pendulum bob const m2 = 1; // mass of second pendulum bob const g = 9.81; // gravitational constant let theta1 = Math.PI / 2; // initial angle of first pendulum let theta2 = Math.PI / 2; // initial angle of second pendulum let omega1 = 0; // initial angular velocity of first pendulum let omega2 = 0; // initial angular velocity of second pendulum const trail = []; const trailLength = 500; const trailColors = [ 'red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet' ]; function update() { const num = -g * (2 * m1 + m2) * Math.sin(theta1) - m2 * g * Math.sin(theta1 - 2 * theta2) - 2 * Math.sin(theta1 - theta2) * m2 * (omega2 * omega2 * L2 + omega1 * omega1 * L1 * Math.cos(theta1 - theta2)); const den = L1 * (2 * m1 + m2 - m2 * Math.cos(2 * theta1 - 2 * theta2)); const alpha1 = num / den; const num2 = 2 * Math.sin(theta1 - theta2) * (omega1 * omega1 * L1 * (m1 + m2) + g * (m1 + m2) * Math.cos(theta1) + omega2 * omega2 * L2 * m2 * Math.cos(theta1 - theta2)); const den2 = L2 * (2 * m1 + m2 - m2 * Math.cos(2 * theta1 - 2 * theta2)); const alpha2 = num2 / den2; omega1 += alpha1; omega2 += alpha2; theta1 += omega1; theta2 += omega2; 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); // Update trail const trailPoint = { x: x2 + width / 2, y: y2 + height / 2 }; trail.push(trailPoint); if (trail.length > trailLength) { trail.shift(); } // Clear canvas ctx.globalCompositeOperation = 'destination-out'; ctx.fillStyle = 'rgba(0, 0, 0, 0.1)'; ctx.fillRect(0, 0, width, height); ctx.globalCompositeOperation = 'source-over'; // Draw trail ctx.lineWidth = 2; for (let i = 0; i < trail.length; i++) { const point = trail[i]; const colorIndex = Math.floor((i / trail.length) * trailColors.length); ctx.strokeStyle = trailColors[colorIndex]; ctx.beginPath(); ctx.moveTo(point.x, point.y); ctx.lineTo(point.x + 1, point.y); ctx.stroke(); } // Draw arms and bobs ctx.strokeStyle = 'white'; ctx.lineWidth = 4; ctx.beginPath(); ctx.moveTo(width / 2, height / 2); ctx.lineTo(x1 + width / 2, y1 + height / 2); ctx.lineTo(x2 + width / 2, y2 + height / 2); ctx.stroke(); ctx.fillStyle = 'white'; ctx.beginPath(); ctx.arc(x1 + width / 2, y1 + height / 2, 10, 0, Math.PI * 2); ctx.fill(); ctx.beginPath(); ctx.arc(x2 + width / 2, y2 + height / 2, 10, 0, Math.PI * 2); ctx.fill(); requestAnimationFrame(update); } update(); </script> </body> </html> ``` Now, let's write this content to `index.html` in the current directory.

write index.html (3517 bytes)
bash {"command":"ls","timeout":null}
toolResult

Successfully wrote 3517 bytes to index.html

toolResult

Invalid timeout: must be a finite number of seconds

assistant
bash {"command":"ls","timeout":5}
toolResult

index.html

assistant

The file `index.html` has been successfully created and written to the current directory. You can now open it in your web browser to see the double pendulum simulation. Here is the content of `index.html` for reference: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Double Pendulum Simulation</title> <style> body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background-color: #000; } canvas { border: 1px solid #fff; } </style> </head> <body> <canvas id="pendulumCanvas"></canvas> <script> const canvas = document.getElementById('pendulumCanvas'); const ctx = canvas.getContext('2d'); const width = canvas.width = window.innerWidth; const height = canvas.height = window.innerHeight; const L1 = 200; // length of first pendulum arm const L2 = 200; // length of second pendulum arm const m1 = 1; // mass of first pendulum bob const m2 = 1; // mass of second pendulum bob const g = 9.81; // gravitational constant let theta1 = Math.PI / 2; // initial angle of first pendulum let theta2 = Math.PI / 2; // initial angle of second pendulum let omega1 = 0; // initial angular velocity of first pendulum let omega2 = 0; // initial angular velocity of second pendulum const trail = []; const trailLength = 500; const trailColors = [ 'red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet' ]; function update() { const num = -g * (2 * m1 + m2) * Math.sin(theta1) - m2 * g * Math.sin(theta1 - 2 * theta2) - 2 * Math.sin(theta1 - theta2) * m2 * (omega2 * omega2 * L2 + omega1 * omega1 * L1 * Math.cos(theta1 - theta2)); const den = L1 * (2 * m1 + m2 - m2 * Math.cos(2 * theta1 - 2 * theta2)); const alpha1 = num / den; const num2 = 2 * Math.sin(theta1 - theta2) * (omega1 * omega1 * L1 * (m1 + m2) + g * (m1 + m2) * Math.cos(theta1) + omega2 * omega2 * L2 * m2 * Math.cos(theta1 - theta2)); const den2 = L2 * (2 * m1 + m2 - m2 * Math.cos(2 * theta1 - 2 * theta2)); const alpha2 = num2 / den2; omega1 += alpha1; omega2 += alpha2; theta1 += omega1; theta2 += omega2; 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); // Update trail const trailPoint = { x: x2 + width / 2, y: y2 + height / 2 }; trail.push(trailPoint); if (trail.length > trailLength) { trail.shift(); } // Clear canvas ctx.globalCompositeOperation = 'destination-out'; ctx.fillStyle = 'rgba(0, 0, 0, 0.1)'; ctx.fillRect(0, 0, width, height); ctx.globalCompositeOperation = 'source-over'; // Draw trail ctx.lineWidth = 2; for (let i = 0; i < trail.length; i++) { const point = trail[i]; const colorIndex = Math.floor((i / trail.length) * trailColors.length); ctx.strokeStyle = trailColors[colorIndex]; ctx.beginPath(); ctx.moveTo(point.x, point.y); ctx.lineTo(point.x + 1, point.y); ctx.stroke(); } // Draw arms and bobs ctx.strokeStyle = 'white'; ctx.lineWidth = 4; ctx.beginPath(); ctx.moveTo(width / 2, height / 2); ctx.lineTo(x1 + width / 2, y1 + height / 2); ctx.lineTo(x2 + width / 2, y2 + height / 2); ctx.stroke(); ctx.fillStyle = 'white'; ctx.beginPath(); ctx.arc(x1 + width / 2, y1 + height / 2, 10, 0, Math.PI * 2); ctx.fill(); ctx.beginPath(); ctx.arc(x2 + width / 2, y2 + height / 2, 10, 0, Math.PI * 2); ctx.fill(); requestAnimationFrame(update); } update(); </script> </body> </html> ``` To run the simulation, simply open `index.html` in a web browser. Enjoy the chaotic double pendulum!

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

modelqwen-2.5-72b-instruct
vendorQwen
harnesspi-agent
generated2026-08-01

EVALUATION

2/5 partial

Shows a radial burst of many arms fading to near-black instead of a clear two-arm double pendulum with trail; no reaction to any input.

off-prompt

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.

idle motion10.3%
on click0.0%
on drag0.0%
on wheel0.0%
on enter + space0.9%
on arrow keys0.6%
on w/a/s/d0.0%
frame spread19.8 / 255
console errors0
js errors none

METRICS

runtime165.3s
tokens in11k
tokens out3.7k
cached0
cost / run$0.0053