11# Nathaniel Morin
22# 8/22/2021
33
4+ from asyncio .tasks import Task
5+ from concurrent .futures .thread import ThreadPoolExecutor
46import pygame
57import math
68import numpy as np
79import itertools
8-
10+ import asyncio
911pygame .init ()
1012
1113# Body class
@@ -24,7 +26,7 @@ class Body:
2426 # What portion of the *radius* of the smaller body (between its and the other body's center) needs to be non-overlapping for it to not collide.
2527 # 1 means that it just needs to be tangential for a collision to be detected, since it means that the whole radius needs to be outside the other body for it not to collide
2628 # 0 means that it needs to be submerged up to its center before it collides
27- collisionDistanceFactor = 0.6
29+ collisionDistanceFactor = 1
2830 # How many times longer the displayed vector is than the distance they will travel in the next frame
2931 vectorDisplayFactor = 10000
3032 # What portion of the real magnitude of the gravity vectors are displayed
@@ -136,11 +138,8 @@ def findGravitationalAttraction(body1, body2):
136138 @staticmethod
137139 def addVectors (vec1 , vec2 ):
138140 return [vec1 [0 ]+ vec2 [0 ], vec1 [1 ]+ vec2 [1 ]]
139-
140- # A function that iterates over a list of bodies and handles collisions between them
141- # returns the new list of bodies (post-collisions)
142141 @staticmethod
143- def checkForBodyCollision (lst ):
142+ def checkForBodyCollisionNoThread (lst ):
144143 # Iterates over all possible body combinations
145144 pairs = list (itertools .combinations (lst , 2 ))
146145 for pair in pairs :
@@ -150,7 +149,7 @@ def checkForBodyCollision(lst):
150149 # true if body1 is bigger and they are colliding
151150 absorb = dist <= body1 .displayRad + body2 .displayRad * Body .collisionDistanceFactor and body1 .mass >= body2 .mass
152151 # if body2 is bigger and they are colliding
153- if dist <= body2 .displayRad + body1 .displayRad * 0.5 and body2 .mass >= body1 .mass :
152+ if dist <= body2 .displayRad + body1 .displayRad * Body . collisionDistanceFactor and body2 .mass >= body1 .mass :
154153 absorb = True
155154 # swapping them so that body1 refers to the larger
156155 temp = body2
@@ -163,6 +162,49 @@ def checkForBodyCollision(lst):
163162 if body2 in lst :
164163 lst .remove (body2 )
165164
165+ # A function that iterates over a list of bodies and handles collisions between them
166+ # returns the new list of bodies (post-collisions)
167+ @staticmethod
168+ async def checkForBodyCollision (lst ):
169+ # Iterates over all possible body combinations
170+ list = await asyncio .gather (* [Body .calculateBody (body , lst ) for body in lst ])
171+ list_new = []
172+ list2 = []
173+ for ele , ele2 in list :
174+ list2 = list2 + ele2
175+ for ele , ele2 in list :
176+ if not ele == False and not ele in list2 :
177+ list_new .append (ele )
178+ return list_new
179+
180+ @staticmethod
181+ async def calculateBody (body1 , lst ):
182+ with ThreadPoolExecutor () as executor :
183+ loop = asyncio .get_running_loop ()
184+ a , list = await loop .run_in_executor (executor , Body .calculateBodyHelper , body1 , lst )
185+ return a , list
186+
187+ @staticmethod
188+ def calculateBodyHelper (body1 , lst ):
189+ list = []
190+ doMoreColisions = True
191+ for body2 in lst :
192+
193+ if (doMoreColisions and body2 != body1 ):
194+ if body1 .released and body2 .released :
195+ dist = Body .findDisplayDistance (body1 .pos , body2 .pos )
196+ # true if body1 is bigger and they are colliding
197+ absorb = dist <= body1 .displayRad + body2 .displayRad * Body .collisionDistanceFactor #and body1.mass >= body2.mass
198+ # if body2 is bigger and they are colliding
199+ if absorb and body1 .mass < body2 .mass :#dist <= body2.displayRad + body1.displayRad*0.5 and body2.mass >= body1.mass:
200+ doMoreColisions = False
201+ return False , list
202+ # absorb = Body.collisionApproximationLinesAreIntersecting(body1, body2, body1.srf)
203+ elif absorb :
204+ list .append (body2 )
205+ body1 .vec = Body .addVectors (body1 .vec , body2 .vec )
206+ body1 .setMass (body1 .mass + body2 .mass )
207+ return body1 , list
166208 # function that iterates over a list of bodies and handles shifts to their vectors due to gravitational interactions
167209 @staticmethod
168210 def applyGravity (lst ):
0 commit comments