Files
INF6B/simulations/pendulum/main.py
rattatwinko d0eaabdd87 some new stuff.
idk its all pretty fun! some C++ too!
2025-10-15 11:16:51 +02:00

93 lines
2.4 KiB
Python

import pygame
import math
# Initialize Pygame
pygame.init()
# Screen setup
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Interactive Adjustable Pendulum")
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (200, 50, 50)
# Clock for FPS
clock = pygame.time.Clock()
FPS = 60
# Pendulum properties
origin = (WIDTH // 2, 100)
length = 300
angle = math.pi / 4
angular_velocity = 0
angular_acceleration = 0
gravity = 0.8
dragging = False
drag_padding = 30 # extra radius for easier dragging
def get_bob_position(angle):
x = origin[0] + length * math.sin(angle)
y = origin[1] + length * math.cos(angle)
return int(x), int(y)
bob_pos = get_bob_position(angle)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Start dragging
elif event.type == pygame.MOUSEBUTTONDOWN:
mx, my = event.pos
if math.hypot(mx - bob_pos[0], my - bob_pos[1]) < 20 + drag_padding:
dragging = True
# Stop dragging
elif event.type == pygame.MOUSEBUTTONUP:
dragging = False
# Keyboard controls
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
length += 1 # increase pendulum length
if keys[pygame.K_DOWN]:
length = max(50, length - 1) # decrease length, min 50
if keys[pygame.K_RIGHT]:
gravity += 0.01
if keys[pygame.K_LEFT]:
gravity = max(0.1, gravity - 0.01)
if dragging:
mx, my = pygame.mouse.get_pos()
dx = mx - origin[0]
dy = my - origin[1]
angle = math.atan2(dx, dy)
angular_velocity = 0
bob_pos = get_bob_position(angle)
else:
# Physics
angular_acceleration = (-gravity / length) * math.sin(angle)
angular_velocity += angular_acceleration
angle += angular_velocity
angular_velocity *= 0.99 # damping
bob_pos = get_bob_position(angle)
# Drawing
screen.fill(BLACK)
pygame.draw.line(screen, WHITE, origin, bob_pos, 3)
pygame.draw.circle(screen, RED, bob_pos, 20)
pygame.draw.circle(screen, WHITE, origin, 5)
# Display info
font = pygame.font.SysFont(None, 24)
info = font.render(f"Length: {int(length)} Gravity: {gravity:.2f}", True, WHITE)
screen.blit(info, (10, 10))
pygame.display.flip()
clock.tick(FPS)
pygame.quit()