I have wrote a script in Python 3 to simulate elastic collisions in two dimensions. I don't know what I am doing wrong because when I run it, the balls seem to stick to each other and sometimes glitch to become one ball. Also, when a single ball hits any edge of the screen, it will bounce off, however when when another ball is stuck to it, it will cause one of them to come off the screen.
Snippet of the code:
class Particle(Sprite):
def __init__(self, image):
super(Particle, self).__init__(image)
self.Vxi, self.Vyi = random.randint(-3, 3), random.randint(-3, 3)
self.mass = random.randint(1, 100) / 1000
self.schedule_interval(self.update, 1/60)
def update(self, dt):
self.xpos, self.ypos = self.position
if self.xpos <= self.width/2 or self.xpos >= scr_width - self.width/2:
self.Vxi *= -1
if self.ypos <= self.width/2 or self.ypos >= scr_height - self.height/2:
self.Vyi *= -1
for particle in director.scene.children[0][1].particles:
particle_xpos, particle_ypos = particle.position
if abs(self.xpos - particle_xpos) <= self.width/2 + particle.width/2:
if abs(self.ypos - particle_ypos) <= self.height/2 + particle.height/2:
xmomentum = (particle.mass * particle.Vxi) + (self.mass * self.Vxi)
ymomentum = (particle.mass * particle.Vyi) + (self.mass * self.Vyi)
Vxf = (xmomentum - particle.mass * (self.Vxi - particle.Vxi)) / (particle.mass + self.mass)
Vyf = (ymomentum - particle.mass * (self.Vyi - particle.Vyi)) / (particle.mass + self.mass)
self.Vxi = Vxf
self.Vyi = Vyf
self.xpos += self.Vxi
self.ypos += self.Vyi
self.position = self.xpos, self.ypos
I think you forgot to update the other particle's velocity upon collision.
Before
self.Vxi = Vxf
self.Vyi = Vyf
there should also be
particle.Vxi = Vxf + (self.Vxi - particle.Vxi)
particle.Vyi = Vyf + (self.Vyi - particle.Vyi)
Style wise, I think the variables can be named better. A Particle object shouldn't have an attribute called Vxi
or Vxf
. As far as the physical particle is concerned it only has one velocity. The concept of initial/final velocities is associated with the numerical simulation, which the attributes of the Particle class shouldn't model. In your current code, the "final" velocities of self
is updated as its initial velocity, which can be confusing.
The initial velocity (Vxi
, Vyi
) should be taken from self.Vx
and self.Vy
at the beginning of update
. At the very end, Vfx
and Vfy
should be updated to self.Vx
and self.Vy
.
Also, it's a good idea to indicate which particle it is in the local variables, eg V1_x_initial
, V2_x_initial
, etc.