1

So I am trying to create a code that will correctly show the elastic collision of two balls of different masses. The code works if I give the balls equal masses but does not work for different masses. I have tried messing around with a ton of stuff but nothing seems to be working. I would love some help;

This is the formula I am trying to implement: https://wikimedia.org/api/rest_v1/media/math/render/svg/14d5feb68844edae9e31c9cb4a2197ee922e409c

global w 
global h
global lst

w = 500
h = 500 
lst = [] 

def setup():
    size(w,h)
    global canvas
    canvas = createGraphics(1000,1000)
    canvas.beginDraw()
    canvas.background(255)
    canvas.endDraw()
    global ball1
    global ball2 
    ball1 = Ball(100,250,1,-.01,10,25)
    ball2 = Ball(300,250,-1,0,20,50)
    lst.append(ball1)
    lst.append(ball2)

def draw():
    background(255)
    textSize(32)
    fill(0, 102, 153);

    for y in range(0,len(last)):
        lst[y].show()
        lst[y].move()

        for z in range(0,y):
            lst[y].collide(lst[z])
        for z in range(y+1, len(last)):
            lst[y].collide(lst[z])
    





class Ball(object):
    def __init__(self,x,y,dx,dy,m,r):
        self.x = x
        self.y = y
        self.dx = dx
        self.dy = dy
        self.m = m
        self.r = r
        self.ball_last_hit = None
    
    
def show(self):
    fill(0)
    ellipse(self.x,self.y,self.r*2,self.r*2)
    
def move(self):
    self.x += self.dx
    self.y += self.dy
    #Makes balls unable to go off of screen
    if self.x >= ( w - self.r):
        self.dx = self.dx * -1
    if self.x <=  self.r:
        self.dx = self.dx * -1
    if self.y >= ( h - self.r):
        self.dy = self.dy * -1
    if self.y <=  self.r:
        self.dy = self.dy * -1
      
def collide(self, other):
    distanceSquared = (self.x - other.x)**2 + (self.y - other.y)**2
    
    initialPositionSelf = PVector(self.x,self.y)
    initialPositionOther = PVector(other.x,other.y)
    xDiff1 = PVector.sub(initialPositionSelf, initialPositionOther)
    xDiff2 = PVector.sub(initialPositionOther, initialPositionSelf)
    
    initialVelocitySelf = PVector(self.dx,self.dy)
    initialVelocityOther = PVector(other.dx,other.dy)
    vDiff1 = PVector.sub(initialVelocitySelf, initialVelocityOther)
    vDiff2 = PVector.sub(initialVelocityOther, initialVelocitySelf)
    
    xDiffSq1 = xDiff1.magSq()
    xDiffSq2 = xDiff2.magSq()
    
    mTot = self.m + other.m
    
    c1 = (2*other.m)/mTot
    c2 = (2*self.m)/mTot
    
    Dot1 = vDiff1.dot(xDiff1)
    Dot2 = vDiff2.dot(xDiff2)
    
    bigConstant1 = (c1*Dot1)/xDiffSq1
    bigConstant2 = (c2*Dot2)/xDiffSq2
    
    V1F = PVector.sub(initialVelocitySelf, xDiff1.mult(bigConstant1))
    V2F = PVector.sub(initialVelocityOther, xDiff2.mult(bigConstant2))
    
    if (self.r + other.r)**2 >= distanceSquared:
        self.dx = V1F.x
        self.dy = V1F.y
        
        other.dx = V2F.x
        other.dy = V2F.y
        
        
        
        
        
    
Corey D
  • 11
  • 3
  • 1
    please include a fully working example. This will greatly increase likelihood that someone gives you a useful answer – anon01 May 23 '21 at 19:50
  • Welcome to Stack Overflow! Please read up on what's expected of a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – CrazyChucky May 23 '21 at 21:33
  • 2
    I think you get the award for funniest question title of 2021 – wim May 23 '21 at 23:45

1 Answers1

0

I guess you need calculate distance between the centers of the circles, but you calculate distance between the top left corners of the circle bounding box. try to change self.x and self.y to self.x+self.r and self.y+self.r (and same for the other). for the collision calculations

Yosef Tukachinsky
  • 5,570
  • 1
  • 13
  • 29
  • Just tried it and I'm getting the same problem, I think it has something to do with the mass since when the masses are equal the code works perfectly. No idea though. Thanks for the help. – Corey D May 24 '21 at 20:05