93 lines
2.4 KiB
Python
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()
|