Advertisement
Guest User

bouncing-ball-bartowski-THUDM_GLM-4-32B-0414-Q4_K_S

a guest
May 4th, 2025
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 5 8.64 KB | Source Code | 0 0
  1. <!doctype html>
  2. <html lang="en">
  3.   <head>
  4.     <meta charset="UTF-8" />
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6.     <title>Bouncing Ball in Rotating Hexagon</title>
  7.     <style>
  8.       body {
  9.         font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
  10.         display: flex;
  11.         flex-direction: column;
  12.         align-items: center;
  13.         justify-content: center;
  14.         min-height: 100vh;
  15.         margin: 0;
  16.         background-color: #f5f7fa;
  17.         color: #333;
  18.       }
  19.  
  20.       h1 {
  21.         margin-bottom: 20px;
  22.         color: #2c3e50;
  23.       }
  24.  
  25.       canvas {
  26.         background-color: #fff;
  27.         border-radius: 8px;
  28.         box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  29.         margin-bottom: 20px;
  30.       }
  31.  
  32.       .controls {
  33.         display: flex;
  34.         gap: 10px;
  35.         margin-bottom: 20px;
  36.       }
  37.  
  38.       button {
  39.         padding: 10px 20px;
  40.         background-color: #3498db;
  41.         color: white;
  42.         border: none;
  43.         border-radius: 4px;
  44.         cursor: pointer;
  45.         font-size: 16px;
  46.         transition: background-color 0.3s;
  47.       }
  48.  
  49.       button:hover {
  50.         background-color: #2980b9;
  51.       }
  52.  
  53.       .info {
  54.         text-align: center;
  55.         max-width: 600px;
  56.         line-height: 1.6;
  57.         color: #7f8c8d;
  58.       }
  59.     </style>
  60.   </head>
  61.   <body>
  62.     <h1>Bouncing Ball in Rotating Hexagon</h1>
  63.  
  64.     <canvas id="canvas" width="500" height="500"></canvas>
  65.  
  66.     <div class="controls">
  67.       <button id="resetBtn">Reset Simulation</button>
  68.       <button id="pauseBtn">Pause/Resume</button>
  69.     </div>
  70.  
  71.     <div class="info">
  72.       Watch as the ball bounces around inside a rotating hexagon. The physics
  73.       simulation includes gravity, bouncing effects, and collision detection
  74.       with the hexagon's edges.
  75.     </div>
  76.  
  77.     <script>
  78.       // Canvas setup
  79.       const canvas = document.getElementById("canvas");
  80.       const ctx = canvas.getContext("2d");
  81.       const width = canvas.width;
  82.       const height = canvas.height;
  83.  
  84.       // Center of the canvas
  85.       const centerX = width / 2;
  86.       const centerY = height / 2;
  87.  
  88.       // Hexagon properties
  89.       const hexRadius = 150;
  90.       let hexRotation = 0;
  91.       const hexRotationSpeed = 0.005; // radians per frame
  92.  
  93.       // Ball properties
  94.       let ball = {
  95.         x: centerX,
  96.         y: centerY - 50,
  97.         radius: 15,
  98.         velocityX: 1,
  99.         velocityY: 0,
  100.         gravity: 0.2,
  101.         friction: 0.99,
  102.         bounce: 0.8,
  103.       };
  104.  
  105.       // Animation control
  106.       let animationId;
  107.       let isPaused = false;
  108.  
  109.       // Hexagon vertices calculation
  110.       function calculateHexVertices() {
  111.         const vertices = [];
  112.         for (let i = 0; i < 6; i++) {
  113.          const angle = hexRotation + ((Math.PI * 2) / 6) * i;
  114.          vertices.push({
  115.            x: centerX + hexRadius * Math.cos(angle),
  116.            y: centerY + hexRadius * Math.sin(angle),
  117.          });
  118.        }
  119.        return vertices;
  120.      }
  121.  
  122.      // Draw the hexagon
  123.      function drawHexagon() {
  124.        const vertices = calculateHexVertices();
  125.  
  126.        ctx.beginPath();
  127.        ctx.moveTo(vertices[0].x, vertices[0].y);
  128.        for (let i = 1; i < vertices.length; i++) {
  129.          ctx.lineTo(vertices[i].x, vertices[i].y);
  130.        }
  131.        ctx.closePath();
  132.  
  133.        ctx.strokeStyle = "#3498db";
  134.        ctx.lineWidth = 3;
  135.        ctx.stroke();
  136.  
  137.        // Fill with semi-transparent color
  138.        ctx.fillStyle = "rgba(52, 152, 219, 0.1)";
  139.        ctx.fill();
  140.      }
  141.  
  142.      // Draw the ball
  143.      function drawBall() {
  144.        ctx.beginPath();
  145.        ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
  146.        ctx.fillStyle = "#e74c3c";
  147.        ctx.fill();
  148.  
  149.        // Add a shine effect to the ball
  150.        const gradient = ctx.createRadialGradient(
  151.          ball.x - ball.radius / 3,
  152.          ball.y - ball.radius / 3,
  153.          0,
  154.          ball.x,
  155.          ball.y,
  156.          ball.radius,
  157.        );
  158.        gradient.addColorStop(0, "rgba(255, 255, 255, 0.8)");
  159.        gradient.addColorStop(1, "rgba(231, 76, 60, 0.8)");
  160.  
  161.        ctx.beginPath();
  162.        ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
  163.        ctx.fillStyle = gradient;
  164.        ctx.fill();
  165.      }
  166.  
  167.      // Check collision between ball and hexagon edges
  168.      function checkCollision() {
  169.        const vertices = calculateHexVertices();
  170.  
  171.        // For each edge of the hexagon
  172.        for (let i = 0; i < vertices.length; i++) {
  173.          const p1 = vertices[i];
  174.          const p2 = vertices[(i + 1) % vertices.length];
  175.  
  176.          // Calculate the closest point on the line segment to the ball center
  177.          const edgeLength = Math.sqrt(
  178.            Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2),
  179.          );
  180.          const dotProduct =
  181.            ((ball.x - p1.x) * (p2.x - p1.x) +
  182.              (ball.y - p1.y) * (p2.y - p1.y)) /
  183.            (edgeLength * edgeLength);
  184.  
  185.          let closestX, closestY;
  186.  
  187.          if (dotProduct < 0) {
  188.            // Closest to p1
  189.            closestX = p1.x;
  190.            closestY = p1.y;
  191.          } else if (dotProduct > 1) {
  192.             // Closest to p2
  193.             closestX = p2.x;
  194.             closestY = p2.y;
  195.           } else {
  196.             // Closest on the line segment
  197.             closestX = p1.x + dotProduct * (p2.x - p1.x);
  198.             closestY = p1.y + dotProduct * (p2.y - p1.y);
  199.           }
  200.  
  201.           // Calculate distance from ball center to closest point
  202.           const distance = Math.sqrt(
  203.             Math.pow(ball.x - closestX, 2) + Math.pow(ball.y - closestY, 2),
  204.           );
  205.  
  206.           // If distance is less than ball radius, collision occurred
  207.           if (distance <= ball.radius) {
  208.            // Calculate normal vector of the edge
  209.            const edgeVectorX = p2.x - p1.x;
  210.            const edgeVectorY = p2.y - p1.y;
  211.  
  212.            // Normalize the edge vector
  213.            const edgeLengthNorm = Math.sqrt(
  214.              edgeVectorX * edgeVectorX + edgeVectorY * edgeVectorY,
  215.            );
  216.            const normalX = -edgeVectorY / edgeLengthNorm; // Perpendicular to edge
  217.            const normalY = edgeVectorX / edgeLengthNorm;
  218.  
  219.            // Calculate dot product of velocity and normal
  220.            const dotVelocityNormal =
  221.              ball.velocityX * normalX + ball.velocityY * normalY;
  222.  
  223.            // Apply bounce effect with the normal
  224.            ball.velocityX -= (1 + ball.bounce) * dotVelocityNormal * normalX;
  225.            ball.velocityY -= (1 + ball.bounce) * dotVelocityNormal * normalY;
  226.  
  227.            // Move ball outside of collision
  228.            const overlap = ball.radius - distance;
  229.            ball.x += overlap * normalX;
  230.            ball.y += overlap * normalY;
  231.          }
  232.        }
  233.      }
  234.  
  235.      // Update ball position and handle physics
  236.      function updateBall() {
  237.        // Apply gravity
  238.        ball.velocityY += ball.gravity;
  239.  
  240.        // Apply friction
  241.        ball.velocityX *= ball.friction;
  242.        ball.velocityY *= ball.friction;
  243.  
  244.        // Update position
  245.        ball.x += ball.velocityX;
  246.        ball.y += ball.velocityY;
  247.  
  248.        // Check collision with hexagon edges
  249.        checkCollision();
  250.      }
  251.  
  252.      // Main animation loop
  253.      function animate() {
  254.        ctx.clearRect(0, 0, width, height);
  255.  
  256.        // Rotate the hexagon
  257.        hexRotation += hexRotationSpeed;
  258.  
  259.        // Draw and update elements
  260.        drawHexagon();
  261.        updateBall();
  262.        drawBall();
  263.  
  264.        // Continue animation
  265.        if (!isPaused) {
  266.          animationId = requestAnimationFrame(animate);
  267.        }
  268.      }
  269.  
  270.      // Reset the simulation
  271.      function resetSimulation() {
  272.        ball = {
  273.          x: centerX,
  274.          y: centerY - 50,
  275.          radius: 15,
  276.          velocityX: Math.random() * 4 - 2, // Random initial X velocity
  277.          velocityY: 0,
  278.          gravity: 0.2,
  279.          friction: 0.99,
  280.          bounce: 0.8,
  281.        };
  282.  
  283.        hexRotation = 0;
  284.  
  285.        if (!animationId && !isPaused) {
  286.          animate();
  287.        }
  288.      }
  289.  
  290.      // Toggle pause/resume
  291.      function togglePause() {
  292.        isPaused = !isPaused;
  293.  
  294.        if (isPaused) {
  295.          cancelAnimationFrame(animationId);
  296.        } else {
  297.          animate();
  298.        }
  299.      }
  300.  
  301.      // Event listeners
  302.      document
  303.        .getElementById("resetBtn")
  304.        .addEventListener("click", resetSimulation);
  305.      document
  306.        .getElementById("pauseBtn")
  307.        .addEventListener("click", togglePause);
  308.  
  309.      // Start the animation
  310.      resetSimulation();
  311.    </script>
  312.   </body>
  313. </html>
  314.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement