Untitled
unknown
plain_text
2 months ago
3.8 kB
2
Indexable
import pygame import math from pygame.math import Vector2 # Initialize pygame pygame.init() # Screen dimensions WIDTH, HEIGHT = 800, 600 screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Bouncing Ball in Spinning Hexagon") clock = pygame.time.Clock() FPS = 60 # Colors WHITE = (255, 255, 255) BLACK = (0, 0, 0) RED = (255, 0, 0) # Hexagon parameters hex_center = Vector2(WIDTH/2, HEIGHT/2) hex_radius = 250 # Distance from center to vertex hex_rotation = 0 # Initial rotation angle in radians angular_velocity = 0.01 # Rotation speed (radians per frame) # Ball parameters ball_radius = 15 ball_pos = Vector2(WIDTH/2, HEIGHT/2 - 100) ball_vel = Vector2(3, 0) gravity = Vector2(0, 0.2) # Constant acceleration downward ball_color = RED # Physics parameters restitution = 0.9 # Bounce damping factor (energy loss on impact) global_friction = 0.999 # Damping applied every frame def compute_hexagon_vertices(center, radius, rotation): """Compute the vertices of a regular hexagon given a center, radius, and rotation.""" vertices = [] for i in range(6): angle = rotation + i * (2 * math.pi / 6) x = center.x + radius * math.cos(angle) y = center.y + radius * math.sin(angle) vertices.append(Vector2(x, y)) return vertices def point_line_distance(p, a, b): """ Returns the distance from point p to the line segment defined by points a and b, along with the closest point on the segment. """ ap = p - a ab = b - a t = ap.dot(ab) / ab.length_squared() t = max(0, min(1, t)) closest = a + ab * t return (p - closest).length(), closest running = True while running: dt = clock.tick(FPS) / 1000.0 # dt in seconds (not used extensively) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # Update hexagon rotation hex_rotation += angular_velocity # Update ball physics: gravity and friction ball_vel += gravity ball_vel *= global_friction ball_pos += ball_vel # Get current hexagon vertices (rotating each frame) vertices = compute_hexagon_vertices(hex_center, hex_radius, hex_rotation) # Check collision with each hexagon edge for i in range(len(vertices)): a = vertices[i] b = vertices[(i+1) % len(vertices)] dist, closest = point_line_distance(ball_pos, a, b) if dist < ball_radius: # Collision detected: compute collision normal (from wall toward ball) normal = (ball_pos - closest).normalize() # Compute the wall's velocity at the collision point due to rotation. # For a rotating body, v = ω × r. Here r = (collision point - hex_center) r = closest - hex_center wall_vel = angular_velocity * Vector2(-r.y, r.x) # Compute ball velocity relative to the moving wall rel_vel = ball_vel - wall_vel # Reflect the relative velocity along the collision normal rel_vel_reflected = rel_vel - 2 * rel_vel.dot(normal) * normal # New ball velocity is the reflected relative velocity plus wall velocity, # scaled by the restitution coefficient to simulate energy loss. ball_vel = wall_vel + rel_vel_reflected * restitution # Reposition ball just outside the wall to prevent sticking. overlap = ball_radius - dist ball_pos += normal * overlap # Drawing screen.fill(BLACK) # Draw hexagon (outline) pygame.draw.polygon(screen, WHITE, [(v.x, v.y) for v in vertices], 2) # Draw ball pygame.draw.circle(screen, ball_color, (int(ball_pos.x), int(ball_pos.y)), ball_radius) pygame.display.flip() pygame.quit()
Editor is loading...
Leave a Comment