Tool Request: call_u1vDgqtQjLMICswPsR16geLz - create_file
{"file_name":"index.html","content":"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Rotating Hexagon with Bouncing Balls</title>\n <style>\n body, html { margin: 0; padding: 0; overflow: hidden; background: #222; }\n canvas { display: block; }\n </style>\n</head>\n<body>\n <canvas id=\"canvas\"></canvas>\n <script>\n const canvas = document.getElementById('canvas');\n const ctx = canvas.getContext('2d');\n let w, h;\n function resize() {\n w = canvas.width = window.innerWidth;\n h = canvas.height = window.innerHeight;\n centerX = w / 2;\n centerY = h / 2;\n }\n window.addEventListener('resize', resize);\n resize();\n\n // Hexagon parameters\n const hexRadius = Math.min(w, h) * 0.4;\n const hexVertices = [];\n const normals = [];\n for (let i = 0; i < 6; i++) {\n const angle = Math.PI / 3 * i - Math.PI / 6;\n const x = Math.cos(angle) * hexRadius;\n const y = Math.sin(angle) * hexRadius;\n hexVertices.push({x, y});\n }\n // Compute inward normals for each edge\n for (let i = 0; i < 6; i++) {\n const p1 = hexVertices[i];\n const p2 = hexVertices[(i + 1) % 6];\n // edge vector\n const ex = p2.x - p1.x;\n const ey = p2.y - p1.y;\n // normal (rotate edge by 90deg)\n let nx = ey;\n let ny = -ex;\n // ensure it's inward: test center (0,0) gives positive\n const dot = nx * (-p1.x) + ny * (-p1.y);\n if (dot < 0) { nx = -nx; ny = -ny; }\n const len = Math.hypot(nx, ny);\n normals.push({nx: nx / len, ny: ny / len, px: p1.x, py: p1.y});\n }\n\n // Balls\n const balls = [];\n const ballCount = 12;\n const ballRadius = 10;\n\n // Point-in-polygon test (convex)\n function insideHex(x, y) {\n for (let e of normals) {\n const d = (x - e.px) * e.nx + (y - e.py) * e.ny;\n if (d < ballRadius) return false;\n }\n return true;\n }\n // random ball init\n for (let i = 0; i < ballCount; i++) {\n let x, y;\n do {\n x = (Math.random() * 2 - 1) * hexRadius;\n y = (Math.random() * 2 - 1) * hexRadius;\n } while (!insideHex(x, y));\n const angle = Math.random() * Math.PI * 2;\n const speed = 2 + Math.random() * 2;\n balls.push({x, y, vx: Math.cos(angle) * speed, vy: Math.sin(angle) * speed});\n }\n\n let angle = 0;\n function animate() {\n ctx.clearRect(0, 0, w, h);\n angle += 0.005;\n\n // draw rotating hexagon\n ctx.save();\n ctx.translate(centerX, centerY);\n ctx.rotate(angle);\n // polygon\n ctx.beginPath();\n ctx.moveTo(hexVertices[0].x, hexVertices[0].y);\n for (let v of hexVertices) ctx.lineTo(v.x, v.y);\n ctx.closePath();\n ctx.strokeStyle = '#0f0'; ctx.lineWidth = 3;\n ctx.stroke();\n\n // update and draw balls in local coords\n for (let b of balls) {\n // move\n b.x += b.vx;\n b.y += b.vy;\n // collision with edges\n for (let e of normals) {\n const d = (b.x - e.px) * e.nx + (b.y - e.py) * e.ny;\n if (d < ballRadius) {\n // push back\n b.x += (ballRadius - d) * e.nx;\n b.y += (ballRadius - d) * e.ny;\n // reflect\n const vDot = b.vx * e.nx + b.vy * e.ny;\n b.vx -= 2 * vDot * e.nx;\n b.vy -= 2 * vDot * e.ny;\n }\n }\n // draw\n ctx.beginPath();\n ctx.arc(b.x, b.y, ballRadius, 0, Math.PI * 2);\n ctx.fillStyle = '#ff3';\n ctx.fill();\n }\n\n ctx.restore();\n requestAnimationFrame(animate);\n }\n animate();\n </script>\n</body>\n</html>"}