oneshotlm
Compare all models on this prompt →

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.

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

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.

assistant
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.

write /tmp/ws/index.html (13566 bytes)
toolResult

Successfully wrote 13566 bytes to /tmp/ws/index.html

assistant
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.

edit {"path":"/tmp/ws/index.html","edits":[{"oldText":"window.addEventListener(\"resize\", function () {\n const oldR = ballR;\n resize();\
toolResult

Successfully replaced 1 block(s) in /tmp/ws/index.html.

assistant
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

modelgrok-4.6
vendorxAI · Grok
harnesspi-agent
generated2026-08-13

EVALUATION

3/5 working

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.

idle motion8.4%
on click8.1%
on drag7.2%
on wheel8.2%
on enter + space7.8%
on arrow keys7.8%
on w/a/s/d7.5%
frame spread23.5 / 255
console errors0
js errors none

METRICS

runtime122.1s
tokens in16k
tokens out9.9k
cached8.6k
cost / run$0.0790