简体   繁体   中英

Using python to simulate 2D elastic collisions

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.

Eqautions that I used

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM