82 lines
2.2 KiB
Python
82 lines
2.2 KiB
Python
"""Hilfsfunktionen für die Physik-Tests (Szenen aufbauen, simulieren, Erhaltungsgrößen)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import replace
|
|
|
|
from sandbox.config import PHYSICS, TIME_STEP
|
|
from sandbox.physics import Body, Material, Vector2, World
|
|
|
|
WORLD_WIDTH = 1000.0
|
|
WORLD_HEIGHT = 700.0
|
|
|
|
|
|
def make_world(
|
|
width: float = WORLD_WIDTH, height: float = WORLD_HEIGHT, **overrides: object
|
|
) -> World:
|
|
"""Welt mit Standardkonfiguration; einzelne Parameter lassen sich überschreiben."""
|
|
return World(width, height, replace(PHYSICS, **overrides))
|
|
|
|
|
|
def material(density: float = 1.0, restitution: float = 0.5, friction: float = 0.5) -> Material:
|
|
"""Material mit gut lesbaren Standardwerten."""
|
|
return Material(density=density, restitution=restitution, friction=friction)
|
|
|
|
|
|
def add_circle(
|
|
world: World,
|
|
x: float,
|
|
y: float,
|
|
radius: float,
|
|
*,
|
|
velocity: tuple[float, float] = (0.0, 0.0),
|
|
angular_velocity: float = 0.0,
|
|
**material_values: float,
|
|
) -> Body:
|
|
"""Fügt einen Kreis hinzu."""
|
|
body = Body.circle(
|
|
Vector2(x, y), radius, material(**material_values), velocity=Vector2(*velocity)
|
|
)
|
|
body.angular_velocity = angular_velocity
|
|
return world.add_body(body)
|
|
|
|
|
|
def add_box(
|
|
world: World,
|
|
x: float,
|
|
y: float,
|
|
half_width: float,
|
|
half_height: float,
|
|
*,
|
|
velocity: tuple[float, float] = (0.0, 0.0),
|
|
**material_values: float,
|
|
) -> Body:
|
|
"""Fügt ein achsenparalleles Rechteck hinzu."""
|
|
body = Body.box(
|
|
Vector2(x, y),
|
|
half_width,
|
|
half_height,
|
|
material(**material_values),
|
|
velocity=Vector2(*velocity),
|
|
)
|
|
return world.add_body(body)
|
|
|
|
|
|
def simulate(world: World, seconds: float, dt: float = TIME_STEP) -> None:
|
|
"""Führt so viele feste Schritte aus, wie in ``seconds`` passen."""
|
|
for _ in range(round(seconds / dt)):
|
|
world.step(dt)
|
|
|
|
|
|
def total_momentum(bodies: list[Body]) -> Vector2:
|
|
"""Summe der Impulse m·v."""
|
|
total = Vector2()
|
|
for body in bodies:
|
|
total = total + body.momentum()
|
|
return total
|
|
|
|
|
|
def total_kinetic_energy(bodies: list[Body]) -> float:
|
|
"""Summe der Bewegungsenergien (translatorisch + rotatorisch)."""
|
|
return sum(body.kinetic_energy() for body in bodies)
|