61 lines
2.3 KiB
Python
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)
|