Bouncing balls in a heptagon · grok-4.6
Show 20 numbered balls (1 to 20) dropping from the center of a heptagon that spins 360 degrees every 5 seconds. The balls are affected by gravity and friction, collide with each other, and bounce realistically off the rotating walls; show each ball's spin via the rotation of its number. Implement all collision detection yourself.
transcript · 6 messages
Show 20 numbered balls (1 to 20) dropping from the center of a heptagon that spins 360 degrees every 5 seconds. The balls are affected by gravity and friction, collide with each other, and bounce realistically off the rotating walls; show each ball's spin via the rotation of its number. Implement all collision detection yourself.
thinking
The user wants me to create a single-page web app with a physics simulation of 20 numbered balls dropping from the center of a spinning heptagon. Let me plan this carefully.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Spinning Heptagon Balls</title>
<style>
body { margin:0; background:#111; display:flex; justify-content:center; align-items:center; height:100vh; font-family: Arial, sans-serif; }
canvas { border: 3px solid #222; box-shadow: 0 0 40px rgba(0,0,0,0.8); }
</style>
</head>
<body>
<canvas id="c" width="800" height="600"></canvas script>
<script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
const W = 800, H = 600;
const G = 0.18;
const FRICTION = 0.96;
const RESTITUTION = 0.78;
const WALL_OMEGA = 2 * Math.PI / 5;
const NUM_BALLS = 20;
const RADIUS = 13;
const MASS = 1;
const I = MASS * RADIUS * RADIUS / 2;
let balls = [];
let heptRotation = 0;
let lastTime = performance.now();
// Create balls
for (let i = 0; i < NUM_BALLS; i++) {
const angle = i * Math.PI * 2 / NUM_BALLS + (Math.random() - 0.5) * 0.6;
const dist = 4 + Math.random * 3;
const x = W / 2 + dist * Math.cos(angle);
const y = H / 2 + dist * Math.sin(angle);
balls.push({
x, y,
vx: (Math.random() - 0.5) * 1.5,
vy : (Math.random() - 0.5) * 1.5 - 2,
omega: (Math.random() - 0.5) * 4,
angle: Math.random() * Math.PI * 2
});
}
function draw() {
ctx.fillStyle = '#0 8 1 4';
ctx.fillRect(0, 0, W, H);
// Heptagon
ctx.save();
ctx.translate(W / 2, H / 2);
ctx.rotate(heptRotation);
ctx.strokeStyle = '#00ffcc';
ctx.line Width = 6;
ctx.shadowBlur = 20;
ctx.shadowColor = '#00ffcc';
ctx.beginPath();
for (let i = 0; i < 7; i++) {
const a = i * Math.Building a self-contained physics demo: spinning heptagon, 20 numbered balls, custom collision and spin.
/tmp/ws/index.html (13566 bytes)Successfully wrote 13566 bytes to /tmp/ws/index.html
thinking
There's a bug in the resize handler - I left leftover broken logic that uses old W/H incorrectly. Let me fix that. Also I should verify the heptagon winding and collision normals. Here's a complete, self-contained HTML/JS demo that does exactly what you asked for. It spins a heptagon at 72° per second, drops numbered balls from the center, applies gravity + friction, handles realistic collisions between balls, and bounces them off the rotating walls with proper spin on the numbers.
Fixing the resize handler so balls stay correctly placed when the canvas size changes.
{"path":"/tmp/ws/index.html","edits":[{"oldText":"window.addEventListener(\"resize\", function () {\n const oldR = ballR;\n resize();\Successfully replaced 1 block(s) in /tmp/ws/index.html.
thinking
The app is complete. Let me summarize what was built.
`index.html` is a self-contained page: 20 numbered balls drop from the center of a heptagon that completes a full turn every 5 seconds. - Gravity, air drag, and Coulomb friction (ball–ball and ball–wall) - Custom collisions: SAT-style wall contacts, circle–circle impulses with rotational coupling so wall motion and friction spin the numbers - Sequential impulses + positional correction, 8 substeps per frame - Click or tap to reset and drop them again
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
Numbered balls drop, settle, and jostle inside a rotating heptagon; input has little visible effect but simulation runs correctly.
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.