lab_geometry/simulation/__init__.py

61 lines
2.3 KiB
Python

from itertools import combinations
from superturtle.movement import fly, no_delay
from superturtle.animation import animate
from simulation.gravity import get_gravity_force
from simulation.collision import collide2d
from simulation.drawing import draw_boundary
class Simulation:
def __init__(self, objects, g=None, e=None, boundary=None):
self.objects = objects
self.g = g
self.e = e
self.boundary = boundary
self.collisions = set()
def run(self, *args):
for frame in animate(*args):
for a, b in combinations(self.objects, 2):
if self.g is not None:
force = get_gravity_force(a, b, self.g)
a.acceleration += force / a.mass
b.acceleration -= force / b.mass
if self.e is not None:
if a.collided_with(b):
self.collide(a, b)
else:
self.clear_collision(a, b)
for obj in self.objects:
if self.boundary:
draw_boundary(self.boundary)
self.bounce_object_if_outside_boundary(obj)
obj.update()
fly(obj.position.x, obj.position.y)
obj.draw()
def collide(self, a, b):
if not self.currently_colliding(a, b):
self.collisions.add((a, b))
av, bv = collide2d(a, b, self.e)
a.velocity = av
b.velocity = bv
def currently_colliding(self, a, b):
return (a, b) in self.collisions or (b, a) in self.collisions
def clear_collision(self, a, b):
if (a, b) in self.collisions:
self.collisions.remove((a, b))
if (b, a) in self.collisions:
self.collisions.remove((b, a))
def bounce_object_if_outside_boundary(self, obj):
if obj.position.x + obj.radius > self.boundary:
obj.velocity.x = -abs(obj.velocity.x)
if obj.position.x - obj.radius < -self.boundary:
obj.velocity.x = abs(obj.velocity.x)
if obj.position.y + obj.radius > self.boundary:
obj.velocity.y = -abs(obj.velocity.y)
if obj.position.y - obj.radius < -self.boundary:
obj.velocity.y = abs(obj.velocity.y)