]> Skullheadx's Git Forge - Collision-Simulation.git/commitdiff
reverted to old way + split wall collision
authorSkullheadx <admonty1@gmail.com>
Thu, 26 Jan 2023 21:57:06 +0000 (16:57 -0500)
committerSkullheadx <admonty1@gmail.com>
Thu, 26 Jan 2023 21:57:06 +0000 (16:57 -0500)
collision.py
display.py
particle.py

index 5d949703e9d7d81aa19732197776b8b05d25fc4a..f28028a93046dcf6ddb24e2cb65fe59dd2df7cd7 100644 (file)
-import numpy as np
 from pygame import Vector2
-from math import sqrt
 from itertools import combinations
 
 
-def handleBoxCollision(particle, box):  # Discrete Collision Detection
-    if particle.left <= box.left or particle.right >= box.right:
-        particle.velocity.x *= -1
-    if particle.bottom >= box.bottom or particle.top <= box.top:
+def detectTopCollision(particle, box):
+    if particle.top <= box.top:
+        return True
+    return False
+
+
+def detectBottomCollision(particle, box):
+    if particle.bottom >= box.bottom:
+        return True
+    return False
+
+
+def detectLeftCollision(particle, box):
+    if particle.left <= box.left:
+        return True
+    return False
+
+
+def detectRightCollision(particle, box):
+    if particle.right >= box.right:
+        return True
+    return False
+
+
+def handleTopCollision(particle, box):
+    particle.velocity.y *= -1
+    # particle.position.y = box.top + particle.radius
+    return True
+
+
+def handleBottomCollision(particle, box):
+    particle.velocity.y *= -1
+    # particle.position.y = box.bottom - particle.radius
+    return True
+
+
+def handleLeftCollision(particle, box):
+    particle.velocity.x *= -1
+    # particle.position.x = box.left + particle.radius
+    return True
+
+
+def handleRightCollision(particle, box):
+    particle.velocity.x *= -1
+    # particle.position.x = box.right - particle.radius
+    return True
+
+
+def handleBoxCollision(particle, box):
+    if detectTopCollision(particle, box) or detectBottomCollision(particle, box):
         particle.velocity.y *= -1
+        return True
+    elif detectLeftCollision(particle, box) or detectRightCollision(particle, box):
+        particle.velocity.x *= -1
+        return True
+    return False
 
 
-def handleParticleCollision(particle1, particle2):  # https://www.vobarian.com/collisions/2dcollisions2.pdf
+def detectParticleCollision(particle1, particle2):
     if particle1.position.distance_to(particle2.position) <= particle1.radius + particle2.radius and \
             particle1 != particle2:
+        return True
+    return False
+
+
+def handleParticleCollision(particle1, particle2):  # https://www.vobarian.com/collisions/2dcollisions2.pdf
+    if detectParticleCollision(particle1, particle2):
+        n = particle2.position - particle1.position
+        un = n / n.magnitude()
+        ut = Vector2(-un.y, un.x)
+
+        v1 = particle1.velocity
+        v2 = particle2.velocity
+
+        v1n = un.dot(v1)
+        v1t = ut.dot(v1)
+        v2n = un.dot(v2)
+        v2t = ut.dot(v2)
+
+        v1t_prime = v1t
+        v2t_prime = v2t
+
+        v1n_prime = (v1n * (particle1.mass - particle2.mass) + 2 * particle2.mass * v2n) / (
+                particle1.mass + particle2.mass)
+        v2n_prime = (v2n * (particle2.mass - particle1.mass) + 2 * particle1.mass * v1n) / (
+                particle1.mass + particle2.mass)
+
+        v1_prime = v1n_prime * un + v1t_prime * ut
+        v2_prime = v2n_prime * un + v2t_prime * ut
+
+        particle1.velocity = v1_prime
+        particle2.velocity = v2_prime
+        return True
+    return False
+
 
-        v1 = np.array(particle1.velocity)
-        v2 = np.array(particle2.velocity)
-        x1 = np.array(particle1.position)
-        x2 = np.array(particle2.position)
-        m1 = particle1.mass
-        m2 = particle2.mass
-
-        v1 = v1 - (2 * m2 / (m1 + m2)) * np.dot(v1 - v2, x1 - x2) / np.linalg.norm(x1 - x2) ** 2 * (x1 - x2)
-        v2 = v2 - (2 * m1 / (m1 + m2)) * np.dot(v2 - v1, x2 - x1) / np.linalg.norm(x2 - x1) ** 2 * (x2 - x1)
-
-        particle1.velocity = Vector2(list(v1))
-        particle2.velocity = Vector2(list(v2))
-
-        # v1 - (2 * m2 / (m1 + m2)) * np.dot(v1 - v2, x1 - x2) / np.linalg.norm(x1 - x2) ** 2 * (x1 - x2)
-        # particle1.velocity = particle1.velocity - (2 * particle2.mass) / (particle1.mass + particle2.mass) * (particle1.velocity - particle2.velocity).dot(particle1.position - particle2.position) / ((particle1.position - particle2.position).normalize() * (particle1.position - particle2.position).normalize()) * (particle1.position - particle2.position)
-        # particle2.velocity = particle2.velocity - (2 * particle1.mass) / (particle1.mass + particle2.mass) * (particle2.velocity - particle1.velocity).dot(particle2.position - particle1.position) / ((particle2.position - particle1.position).normalize() * (particle2.position - particle1.position).normalize()) * (particle2.position - particle1.position)
-
-        # n = particle2.position - particle1.position
-        # un = n / n.magnitude()
-        # ut = Vector2(-un.y, un.x)
-        #
-        # v1 = particle1.velocity
-        # v2 = particle2.velocity
-        #
-        # v1n = un.dot(v1)
-        # v1t = ut.dot(v1)
-        # v2n = un.dot(v2)
-        # v2t = ut.dot(v2)
-        #
-        # v1t_prime = v1t
-        # v2t_prime = v2t
-        #
-        # v1n_prime = (v1n * (particle1.mass - particle2.mass) + 2 * particle2.mass * v2n) / (
-        #         particle1.mass + particle2.mass)
-        # v2n_prime = (v2n * (particle2.mass - particle1.mass) + 2 * particle1.mass * v1n) / (
-        #         particle1.mass + particle2.mass)
-        #
-        # v1_prime = v1n_prime * un + v1t_prime * ut
-        # v2_prime = v2n_prime * un + v2t_prime * ut
-        #
-        # particle1.velocity = v1_prime
-        # particle2.velocity = v2_prime
-
-
-def sweepAndPrune(particle_list):
+def sweepAndPrune(particle_list):  # broad phase collision detection
     particles = particle_list.copy()
 
     particles.sort(key=lambda x: x.position.x)
index acda7436007cbcae54bc6952ab3779144e01b01b..0de96b50c052825d3c1cbe7321a55a67c502da7d 100644 (file)
@@ -4,7 +4,7 @@ import random
 from box import Box
 from colours import *
 from particle import Particle
-from collision import sweepAndPrune, handleParticleCollision
+from collision import sweepAndPrune, handleParticleCollision, detectParticleCollision
 
 pygame.init()
 
@@ -33,7 +33,7 @@ class Display:
         for i in range(1, 1 + cols):
             for j in range(1, 1 + rows):
                 r = random.randint(10, 30)
-                speed = 0.1
+                speed = 0.5
                 self.particles.append(Particle((w * i - w / 2, h * j - h / 2),
                                                ((random.random() - 0.5) * speed, (random.random() - 0.5) * speed),
                                                (0, 0), r, r ** 2 * 3.14, self.collision_objects[0]))
@@ -75,8 +75,7 @@ class Display:
                 self.collided_last_frame.add((particle1, particle2))
                 self.collided_last_frame.add((particle2, particle1))
 
-            if particle1.position.distance_to(particle2.position) > particle1.radius + particle2.radius and \
-                    particle1 != particle2:
+            if not detectParticleCollision(particle1, particle2):
                 self.collided_last_frame.remove((particle1, particle2))
                 self.collided_last_frame.remove((particle2, particle1))
 
index 8cb73902a3570ae81a550940494225fefe821ef5..6619b746b45e6afadbbc2f76c58bb8785a977179 100644 (file)
@@ -3,10 +3,13 @@ from math import copysign
 import pygame
 
 from box import Box
-from collision import handleBoxCollision, handleParticleCollision
+from collision import handleBoxCollision, handleParticleCollision, detectTopCollision, handleTopCollision, \
+    detectBottomCollision, handleBottomCollision, detectLeftCollision, handleLeftCollision, handleRightCollision, \
+    detectRightCollision
 from colours import *
 
 
+
 class Particle:
     speed_limit = 3
 
@@ -26,6 +29,8 @@ class Particle:
 
         self.colour = RED
 
+        self.collided_with_wall = {"top":False, "bottom": False, "left": False, "right": False}
+
 
     def get_next_frame(self, position, velocity, delta):
         vel = pygame.Vector2()
@@ -49,7 +54,30 @@ class Particle:
         self.top = self.position.y - self.radius
         self.bottom = self.position.y + self.radius
 
-        handleBoxCollision(self, self.collision_layer[0])
+        if not self.collided_with_wall["top"] and detectTopCollision(self, self.collision_layer[0]):
+            handleTopCollision(self, self.collision_layer[0])
+            self.collided_with_wall["top"] = True
+        if not detectTopCollision(self, self.collision_layer[0]):
+            self.collided_with_wall["top"] = False
+
+        if not self.collided_with_wall["bottom"] and detectBottomCollision(self, self.collision_layer[0]):
+            handleBottomCollision(self, self.collision_layer[0])
+            self.collided_with_wall["bottom"] = True
+        if not detectBottomCollision(self, self.collision_layer[0]):
+            self.collided_with_wall["bottom"] = False
+
+        if not self.collided_with_wall["left"] and detectLeftCollision(self, self.collision_layer[0]):
+            handleLeftCollision(self, self.collision_layer[0])
+            self.collided_with_wall["left"] = True
+        if not detectLeftCollision(self, self.collision_layer[0]):
+            self.collided_with_wall["left"] = False
+
+        if not self.collided_with_wall["right"] and detectRightCollision(self, self.collision_layer[0]):
+            handleRightCollision(self, self.collision_layer[0])
+            self.collided_with_wall["right"] = True
+        if not detectRightCollision(self, self.collision_layer[0]):
+            self.collided_with_wall["right"] = False
+
 
     def draw(self, surf):
         pygame.draw.circle(surf, self.colour, self.position, self.radius)