]> Skullheadx's Git Forge - Collision-Simulation.git/commitdiff
space partition works better than sweep and prune but slower
authorSkullheadx <admonty1@gmail.com>
Thu, 26 Jan 2023 22:12:04 +0000 (17:12 -0500)
committerSkullheadx <admonty1@gmail.com>
Thu, 26 Jan 2023 22:12:04 +0000 (17:12 -0500)
collision.py
display.py

index 68af174e3b8fb274a798aca2fbf6df420a51852d..4fd35d3113d2e7c81944a031d9bf46f2657fb02e 100644 (file)
@@ -144,3 +144,44 @@ def intersection(arr1, arr2):
 
 def remove_duplicates(arr1, arr2):
     return list(set(arr1 + arr2))
+
+
+def spacePartitioning(particle_list, width, height):  # broad phase collision detection
+
+    n = 3
+
+    grid = [[[] for _ in range(n)] for _ in range(n)]
+
+    for particle in particle_list:
+        x1 = int(particle.left // (width / n))
+        x2 = int(particle.right // (width / n))
+        y1 = int(particle.top // (height / n))
+        y2 = int(particle.bottom // (height / n))
+        if x1 < 0:
+            x1 = 0
+        if x2 < 0:
+            x2 = 0
+        if y1 < 0:
+            y1 = 0
+        if y2 < 0:
+            y2 = 0
+        if x1 >= n:
+            x1 = n - 1
+        if x2 >= n:
+            x2 = n - 1
+        if y1 >= n:
+            y1 = n - 1
+        if y2 >= n:
+            y2 = n - 1
+
+        grid[y1][x1].append(particle)
+        grid[y1][x2].append(particle)
+        grid[y2][x1].append(particle)
+        grid[y2][x2].append(particle)
+
+    checks = []
+    for i in range(n):
+        for j in range(n):
+            checks.extend(tuple(combinations(grid[i][j], 2)))
+
+    return list(set(checks))
index c1777e6459d750165a2e2fde3dafc935d9f194ce..7195de8df156583964709342a29915eb1d1c230c 100644 (file)
@@ -3,7 +3,7 @@ import random
 import pygame
 
 from box import Box
-from collision import sweepAndPrune, handleParticleCollision, detectParticleCollision
+from collision import sweepAndPrune, handleParticleCollision, detectParticleCollision, spacePartitioning
 from colours import *
 from particle import Particle
 
@@ -68,7 +68,7 @@ class Display:
         for particle in self.particles:
             particle.update(delta)
 
-        for particle1, particle2 in sweepAndPrune(self.particles):
+        for particle1, particle2 in spacePartitioning(self.particles, self.WIDTH, self.HEIGHT):
             if (particle1, particle2) not in self.collided_last_frame and (
                     particle2, particle1) not in self.collided_last_frame:
                 handleParticleCollision(particle1, particle2)
@@ -77,8 +77,11 @@ class Display:
                 self.collided_last_frame.add((particle2, particle1))
 
             if not detectParticleCollision(particle1, particle2):
-                self.collided_last_frame.remove((particle1, particle2))
-                self.collided_last_frame.remove((particle2, particle1))
+                if self.collided_last_frame.__contains__((particle1, particle2)):
+                    self.collided_last_frame.remove((particle1, particle2))
+                if self.collided_last_frame.__contains__((particle2, particle1)):
+                    self.collided_last_frame.remove((particle2, particle1))
+
 
     def draw(self, surf):
         surf.fill(BLACK)