From: Skullheadx Date: Thu, 26 Jan 2023 17:03:45 +0000 (-0500) Subject: elastic collision with other particles X-Git-Url: http://git.skullheadx.com/nixos/tech/openbsd_html_css/post.html?a=commitdiff_plain;h=23b041d55276be5437a9fff8d2932a889d77347e;p=Collision-Simulation.git elastic collision with other particles - added mass --- diff --git a/collision.py b/collision.py index 7bd892c..3df7540 100644 --- a/collision.py +++ b/collision.py @@ -1,5 +1,33 @@ +from pygame import Vector2 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: particle.velocity.y *= -1 + + +def handleParticleCollision(particle1, particle2): # https://www.vobarian.com/collisions/2dcollisions2.pdf + if particle1.position.distance_to(particle2.position) <= particle1.radius + particle2.radius and 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 \ No newline at end of file diff --git a/display.py b/display.py index 77f738e..607cffe 100644 --- a/display.py +++ b/display.py @@ -1,4 +1,5 @@ import pygame +import random from box import Box from colours import * @@ -21,10 +22,12 @@ class Display: pygame.display.set_caption(window_name) self.collision_objects = {layer: [] for layer in range(self.COLLISION_LAYERS)} + self.particles = [Particle(self.CENTER, (random.random() * 0.75, random.random() * 0.75), (0, 0), 35, 15, self.collision_objects[0]), + Particle((self.WIDTH/3, self.HEIGHT/3), (random.random() * 0.75, random.random() * 0.75), (0, 0), 35, 25, self.collision_objects[0]) + ] + self.box = Box((0, 0), self.WIDTH, self.HEIGHT) - self.particles = [Particle(self.CENTER, (0, 0.5), (0, 0), 15, self.collision_objects[0])] self.collision_objects[0] += self.particles - self.box = Box((0, 0), self.WIDTH, self.HEIGHT) self.collision_objects[0].append(self.box) def show(self): diff --git a/particle.py b/particle.py index 6e6f742..45961cc 100644 --- a/particle.py +++ b/particle.py @@ -3,18 +3,19 @@ from math import copysign import pygame from box import Box -from collision import handleBoxCollision +from collision import handleBoxCollision, handleParticleCollision from colours import * class Particle: speed_limit = 3 - def __init__(self, initial_position, initial_velocity, initial_acceleration, radius, collision_layer): + def __init__(self, initial_position, initial_velocity, initial_acceleration, radius, mass, collision_layer): self.position = pygame.Vector2(initial_position) self.velocity = pygame.Vector2(initial_velocity) self.acceleration = pygame.Vector2(initial_acceleration) self.radius = radius + self.mass = mass self.left = self.position.x - self.radius self.right = self.position.x + self.radius @@ -48,6 +49,8 @@ class Particle: for thing in self.collision_layer: if isinstance(thing, Box): handleBoxCollision(self, thing) + elif isinstance(thing, Particle): + handleParticleCollision(self, thing) def draw(self, surf): pygame.draw.circle(surf, RED, self.position, self.radius)