Created
September 30, 2025 22:18
-
-
Save Khurdhula-Harshavardhan/3d459797b23d2047886fc03606961969 to your computer and use it in GitHub Desktop.
Interfaze Simulation Text
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import math | |
| import sys | |
| import pygame | |
| # Config | |
| WIDTH, HEIGHT = 800, 800 | |
| FPS = 120 | |
| # Physics | |
| GRAVITY = 980.0 # pixels/s^2, roughly Earth-like (tunable) | |
| BOUNCE_DAMPING = 0.85 # energy loss on bounce | |
| FRICTION_TANGENTIAL = 0.995 # slight tangential damping on each collision | |
| # Square | |
| SQUARE_SIZE = 500 # side length in pixels | |
| SQUARE_ROT_SPEED = math.radians(10) # radians per second (slow rotation) | |
| # Ball | |
| BALL_RADIUS = 14 | |
| BALL_COLOR = (255, 215, 0) # gold/yellow | |
| # Colors | |
| BG = (18, 18, 22) | |
| SQUARE_COLOR = (90, 200, 255) | |
| SQUARE_OUTLINE = (170, 220, 255) | |
| def rotate_point(px, py, angle): | |
| ca = math.cos(angle) | |
| sa = math.sin(angle) | |
| return (px * ca - py * sa, px * sa + py * ca) | |
| def clamp(x, a, b): | |
| return max(a, min(b, x)) | |
| def main(): | |
| pygame.init() | |
| screen = pygame.display.set_mode((WIDTH, HEIGHT)) | |
| pygame.display.set_caption("Bouncing Ball in Rotating Square") | |
| clock = pygame.time.Clock() | |
| # Square state | |
| cx, cy = WIDTH // 2, HEIGHT // 2 | |
| half = SQUARE_SIZE / 2 | |
| angle = 0.0 | |
| # Ball initial state (start near the top-center inside the square) | |
| bx, by = cx, cy - half + BALL_RADIUS + 5 | |
| vx, vy = 120.0, 0.0 # give it some initial horizontal motion | |
| running = True | |
| while running: | |
| dt = clock.tick(FPS) / 1000.0 # seconds | |
| for event in pygame.event.get(): | |
| if event.type == pygame.QUIT: | |
| running = False | |
| if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: | |
| running = False | |
| # Update square rotation | |
| angle += SQUARE_ROT_SPEED * dt | |
| # 1) Apply gravity in world space | |
| vy += GRAVITY * dt | |
| # 2) Provisional position update in world space | |
| bx += vx * dt | |
| by += vy * dt | |
| # 3) Transform ball into square's local coordinates (unrotated box space) | |
| # Translate to square center, then rotate by -angle | |
| dx, dy = bx - cx, by - cy | |
| local_x, local_y = rotate_point(dx, dy, -angle) | |
| # Transform velocity into local space (rotate by -angle) | |
| local_vx, local_vy = rotate_point(vx, vy, -angle) | |
| # 4) Collision detection/response in local AABB space | |
| # Effective AABB for the ball is reduced by radius so the ball's center stays within. | |
| min_x = -half + BALL_RADIUS | |
| max_x = half - BALL_RADIUS | |
| min_y = -half + BALL_RADIUS | |
| max_y = half - BALL_RADIUS | |
| collided = False | |
| normal_x, normal_y = 0.0, 0.0 | |
| if local_x < min_x: | |
| local_x = min_x | |
| local_vx = -local_vx * BOUNCE_DAMPING | |
| local_vy *= FRICTION_TANGENTIAL | |
| collided = True | |
| normal_x, normal_y = 1.0, 0.0 | |
| elif local_x > max_x: | |
| local_x = max_x | |
| local_vx = -local_vx * BOUNCE_DAMPING | |
| local_vy *= FRICTION_TANGENTIAL | |
| collided = True | |
| normal_x, normal_y = -1.0, 0.0 | |
| if local_y < min_y: | |
| local_y = min_y | |
| local_vy = -local_vy * BOUNCE_DAMPING | |
| local_vx *= FRICTION_TANGENTIAL | |
| collided = True | |
| normal_x, normal_y = 0.0, 1.0 | |
| elif local_y > max_y: | |
| local_y = max_y | |
| local_vy = -local_vy * BOUNCE_DAMPING | |
| local_vx *= FRICTION_TANGENTIAL | |
| collided = True | |
| normal_x, normal_y = 0.0, -1.0 | |
| # 5) Transform corrected local position/velocity back to world space | |
| world_dx, world_dy = rotate_point(local_x, local_y, angle) | |
| bx, by = cx + world_dx, cy + world_dy | |
| world_vx, world_vy = rotate_point(local_vx, local_vy, angle) | |
| vx, vy = world_vx, world_vy | |
| # Optional: small global damping to avoid runaway energies | |
| vx *= 0.999 | |
| vy *= 0.999 | |
| # 6) Render | |
| screen.fill(BG) | |
| # Compute square corners for drawing | |
| corners_local = [ | |
| (-half, -half), | |
| (half, -half), | |
| (half, half), | |
| (-half, half), | |
| ] | |
| corners_world = [] | |
| for px, py in corners_local: | |
| rx, ry = rotate_point(px, py, angle) | |
| corners_world.append((cx + rx, cy + ry)) | |
| # Filled square (slightly transparent effect by drawing polygon then outline) | |
| pygame.draw.polygon(screen, SQUARE_COLOR, corners_world, width=0) | |
| pygame.draw.polygon(screen, SQUARE_OUTLINE, corners_world, width=3) | |
| # Ball | |
| pygame.draw.circle(screen, BALL_COLOR, (int(bx), int(by)), BALL_RADIUS) | |
| # HUD | |
| font = pygame.font.SysFont(None, 22) | |
| info = f"Angle: {math.degrees(angle) % 360:6.2f} deg | v=({vx:7.2f},{vy:7.2f}) | dt={dt * 1000:5.1f}ms" | |
| screen.blit(font.render(info, True, (230, 230, 235)), (10, 10)) | |
| pygame.display.flip() | |
| pygame.quit() | |
| sys.exit() | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment