Created
February 1, 2025 20:14
-
-
Save Impulsleistung/9d1bd7aebf2df699f27cd57ce5e61435 to your computer and use it in GitHub Desktop.
animation of spring-mass-damper system with realistic physics
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 pygame | |
import pymunk | |
import pymunk.pygame_util | |
import numpy as np | |
from scipy.signal import sawtooth | |
# Initialisierung | |
pygame.init() | |
WIDTH, HEIGHT = 800, 600 | |
window = pygame.display.set_mode((WIDTH, HEIGHT)) | |
clock = pygame.time.Clock() | |
# Physik-Space konfigurieren | |
space = pymunk.Space() | |
space.gravity = (0, 900) # Schwerkraft | |
draw_options = pymunk.pygame_util.DrawOptions(window) | |
# Boden erstellen | |
ground = pymunk.Segment(space.static_body, (0, 550), (WIDTH, 550), 5) | |
ground.friction = 1.0 | |
space.add(ground) | |
# Anregungsparameter | |
PERIODE = 3.0 # 3 Sekunden Periodendauer | |
AMPLITUDE = 100 # Vertikale Amplitude in Pixel | |
# Feder-Ankerpunkt (kinematischer Körper für Bewegung) | |
anchor = pymunk.Body(body_type=pymunk.Body.KINEMATIC) | |
anchor.position = (400, 300) | |
space.add(anchor) | |
# Masse erstellen | |
mass = pymunk.Body() | |
mass.position = (400, 400) | |
shape = pymunk.Poly.create_box(mass, (30, 30)) | |
shape.mass = 8.0 | |
shape.friction = 0.5 | |
space.add(mass, shape) | |
# Feder-Dämpfer-System | |
spring = pymunk.DampedSpring( | |
anchor, | |
mass, | |
(0, 0), | |
(0, 0), | |
rest_length=100, | |
stiffness=120, # Federkonstante | |
damping=15, # Dämpfungskoeffizient | |
) | |
space.add(spring) | |
# Dreieckfunktion für vertikale Anregung | |
def triangle_wave(t): | |
phase = sawtooth(2 * np.pi * t / PERIODE, width=0.5) | |
return AMPLITUDE * phase | |
# Hauptsimulationsschleife | |
running = True | |
start_time = pygame.time.get_ticks() | |
while running: | |
# Zeitberechnung | |
current_time = (pygame.time.get_ticks() - start_time) / 1000.0 | |
# Ankerposition aktualisieren | |
anchor.position = (400, 300 + triangle_wave(current_time)) | |
# Events verarbeiten | |
for event in pygame.event.get(): | |
if event.type == pygame.QUIT: | |
running = False | |
# Physik-Update | |
space.step(1 / 60) | |
# Zeichnen | |
window.fill((30, 30, 30)) | |
space.debug_draw(draw_options) | |
pygame.draw.line(window, (255, 255, 255), anchor.position, mass.position, 3) | |
pygame.display.flip() | |
clock.tick(60) | |
pygame.quit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment