Dominic
Dominic

Reputation: 3

Problems implementing equation for 2d elastic collision

So i am trying to make a 2d ball physics simulator. Before I try to jump ahead and implement visuals i am testing how the physics are going to work, and I am stuck on implementing this equation. This is where i have gotten up to so far:

import math

b1m = 50  # ball 1 mass
b2m = 40  # ball 2 mass
 
b1vx = 35  # ball 1 velocity x
b1vy = 10  # ball 1 velocity y
b2vx = -15  # ball 2 velocity x
b2vy = -40  # ball 2 velocity y

b1v = math.sqrt(abs(b1vx) + abs(b1vy))  # ball 1 velocity | calculates overall velocity/speed
b2v = math.sqrt(abs(b2vx) + abs(b2vy))  # ball 2 velocity | calculates overall velocity/speed

b1ma = math.degrees(math.atan2(b1vy, b1vx)) % 360  # ball 1 movement angle | calculates the angle at 
which the ball is travelling
b2ma = math.degrees(math.atan2(b2vy, b2vx)) % 360  # ball 2 movement angle | calculates the angle at 
which the ball is travelling

ca = 31.5  # contact angle

b1vx = (b1v * math.cos(b1ma - ca) * (b1m - b2m) + 2 * b2m * math.cos(b2ma - ca)) / (b1m + b2m) * 
math.cos(ca) + b1v * math.sin(b1ma - ca) * math.cos(ca + (math.pi/2))
b1vy = (b1v * math.cos(b1ma - ca) * (b1m - b2m) + 2 * b2m * math.cos(b2ma - ca)) / (b1m + b2m) * 
math.sin(ca) + b1v * math.sin(b1ma - ca) * math.sin(ca + (math.pi/2))

print(b1vx)  # print to check if correct values | correct value should be -17.11
print(b1vy)  # print to check if correct values | correct value should be 21.94
#  according to http://www.sciencecalculators.org/mechanics/collisions/

I am not sure whats going wrong but its producing the wrong results for the variables I have asigned. I tried converting the angles to radians, as I know thats python default, I tried editing the equation slightly, seeing if the order of operation had been messed up. But still no results. I'm basing the values needed off of this website, which shows a 2d ball simulation based off of user given variables. Any help is greatly appreciated!

Upvotes: 0

Views: 315

Answers (1)

BenB
BenB

Reputation: 658

Thanks for the interesting question, I liked working on it. There are 3 problems in your code:

  • The total velocity of both balls depends on the square root of the sum of the squared components (Pythagorean theorem). The individual components were not squared in your code
  • In your formula to calculate the resulting velocities, a component is missing in the numerator: b2v (in 2* m2 * v2 * cos(θ2−φ))
  • math.cos and math.sin bith take angular values in radians as input.

By fixing all three I was able to reproduce the expected values. However, while typing this answer I noticed that the velocity in y direction had the wrong sign. The same was true for the y component of the second ball. I checked the equations again, but was unable to spot another mistake. However, if you look at the animation of the website you linked you can see that the ball is moving towards the lower left of the animation, so x and y seem to be negative. I played with different input values and the movement direction of the ball never fitted to its presented y velocity. Unless there is some obvious sign inversion I am missing, this might be an error on that website.

Here's the code:

import math

b1m = 50  # ball 1 mass
b2m = 40  # ball 2 mass
 
b1vx = 35  # ball 1 velocity x
b1vy = 10  # ball 1 velocity y
b2vx = -15  # ball 2 velocity x
b2vy = -40  # ball 2 velocity y


#1 square root of squared components
b1v = math.sqrt(b1vx**2 + b1vy**2)  # ball 1 velocity | calculates overall velocity/speed
b2v = math.sqrt(b2vx**2 + b2vy**2)  # ball 2 velocity | calculates overall velocity/speed

# ball 1 movement angle | calculates the angle at which the ball is travelling
b1ma = math.atan2(b1vy, b1vx)                                                
# ball 2 movement angle | calculates the angle at which the ball is travelling
b2ma = math.atan2(b2vy, b2vx)                                                   

ca = math.radians(31.5)  # contact angle

#3 component missing in second component of numerator of fraction (b2v)
b1vx = ((b1v * math.cos(b1ma - ca) * (b1m - b2m) + 2 * b2m * b2v * math.cos(b2ma - ca)) / (b1m + b2m)) * math.cos(ca) + b1v * math.sin(b1ma - ca) * math.cos(ca + (math.pi/2))
b1vy = ((b1v * math.cos(b1ma - ca) * (b1m - b2m) + 2 * b2m * b2v * math.cos(b2ma - ca)) / (b1m + b2m)) * math.sin(ca) + b1v * math.sin(b1ma - ca) * math.sin(ca + (math.pi/2))

b2vx = ((b2v * math.cos(b2ma - ca) * (b2m - b1m) + 2 * b1m * b1v * math.cos(b1ma - ca)) / (b2m + b1m)) * math.cos(ca) + b2v * math.sin(b2ma - ca) * math.cos(ca + (math.pi/2))
b2vy = ((b2v * math.cos(b2ma - ca) * (b2m - b1m) + 2 * b1m * b1v * math.cos(b1ma - ca)) / (b2m + b1m)) * math.sin(ca) + b2v * math.sin(b2ma - ca) * math.sin(ca + (math.pi/2))



print(b1vx)  # print to check if correct values | correct value should be -17.11
print(b1vy)  # print to check if correct values | correct value should be 21.94

print(b2vx)
print(b2vy)

#  according to http://www.sciencecalculators.org/mechanics/collisions/

Upvotes: 1

Related Questions