Reputation: 426
I am trying to create a simple program for a billiard game where two balls (a) and (b) having radius (R) collides. I created a python program and its like this.
from math import sqrt, atan2, sin, cos, pi, inf
from numpy import array
W = 600 # width of the table
H = 300 # height of the table
R = 10 # the radius of the ball
A = 0 # deceleration constant
dt = 10 ** -3
ma = mb = 1 # masses of the particles a and b
def vec_magnitude(V1):
return sqrt(V1[0]**2 + V1[1]**2)
def collision_test(V1, V2):
if vec_magnitude(V1 - V2) <= 2 * R:
return True
def dot_product(V1, V2):
return sum(V1 * V2)
def after_collision_velocity(Va, Vb, Ra, Rb):
''' the equation that produces the velocity of the objects after the collision'''
Va_new = Va - ((2 * mb * dot_product(Va - Vb, Ra - Rb)) /
((ma + mb) * (vec_magnitude(Ra - Rb))**2) * (Ra - Rb))
Vb_new = Vb - ((2 * ma * dot_product(Vb - Va, Rb - Ra)) /
((ma + mb) * (vec_magnitude(Rb - Ra))**2) * (Rb - Ra))
return Va_new, Vb_new
def motion(P, V_mag, angle, V):
'''describes the motion of the ball'''
if P[1] < R: #reflection from top
P += array([0, 2 * (R - P[1])])
angle *= -1 #reflection from the angular perspective
return P, V_mag, angle, V
if P[0] < R: # reflection from left
P += array([2 * (R - P[0]), 0])
angle = pi - angle
return P, V_mag, angle, V
if P[1] > H - R: #reflection from bottom
P += array([0, 2 * (H - R - P[1])])
angle *= -1
return P, V_mag, angle, V
if P[0] > W - R: #reflection from right
P += array([2 * (W - R - P[0]), 0])
angle = pi - angle
return P, V_mag, angle, V
else:
V_mag -= A * dt
Vx = V_mag * cos(angle)
Vy = V_mag * sin(angle)
P += array([Vx * dt, Vy * dt])
V = array([Vx, Vy])
return P, V_mag, angle, V
file = open("test_drawing.txt", "w")
for line in open("tex.txt", "r"):
t = 0 # starting time
Xa, Ya, Xb, Yb, Vxa, Vya, Vxb, Vyb = [
int(i) for i in (line.rstrip()).split(" ")]
Pa = array([Xa, Ya], dtype=float) #position vector of the ball a
Pb = array([Xb, Yb], dtype=float) #position vector of the ball b
Va = array([Vxa, Vya], dtype=float) #velocity vvector of the ball a
Vb = array([Vxb, Vyb], dtype=float) #velocity vector of the ball b
Va_mag = vec_magnitude(Va)
Vb_mag = vec_magnitude(Vb)
if Vxa == 0: #these steps are necessarry to eliminate error on the angle process
Vxa = inf
angle_a = atan2(Vya, Vxa) # angle between velocity components of the ball a
if Vxb == 0:
Vxb = inf
angle_b = atan2(Vyb, Vxb) # angle between velocity components of the ball b
while t <= 10:
Pa, Va_mag, angle_a, Va = motion(Pa, Va_mag, angle_a, Va) #moving the ball a
Pb, Vb_mag, angle_b, Vb = motion(Pb, Vb_mag, angle_b, Vb) #moving the ball b
if collision_test(Pa, Pb) == True: #checking the collision validity
Va, Vb = after_collision_velocity(Va, Vb, Pa, Pb)
Va_mag = vec_magnitude(Va) #restating the velocities
Vb_mag = vec_magnitude(Vb)
if Va[0] == 0:
Va[0] = inf
angla_a = atan2(Va[1], Va[0]) #restating the angles
if Vb[0] == 0:
Vb[0] = inf
angle_b = atan2(Vb[1], Vb[0])
t += dt #incrementing time
file.write(str(Pa[0]) + " " + str(Pa[1]) + " " + str(Pb[0]) + " " + str(Pb[1]) + "\n")
print(Pa[0], Pa[1], Pb[0], Pb[1])
file.close()
when I draw a picture for a simple collision, which the data file would contain, (the input data)
100 200 140 200 4 4 -4 4
Values,
I get something like
I used this program to draw
from pylab import plot, show
Xa = [100] #X component of the ball a
Ya = [200] #Y component of the ball a
Xb = [140] #X compnonent of the ball b
Yb = [200] $ Y component of the ball b
for line in open("test_drawing.txt", "r"):
data = [float(i) for i in line.split(" ")]
Xa.append(data[0])
Ya.append(data[1])
Xb.append(data[2])
Yb.append(data[3])
plot(Xa, Ya, "-r")
plot(Xb, Yb, "-.g")
show()
As you can see, ball (b) bounces but not the ball (a). To determine the velocity I used the equation in wikipedia page of the elastic collision.
https://en.wikipedia.org/wiki/Elastic_collision
Can anyone understand why this happens ?
Upvotes: 0
Views: 869
Reputation: 4653
You have a typo.
angla_a = atan2(Va[1], Va[0]) #restating the angles
should say angle_a
. You are never actually updating angle_a
after a collision.
Upvotes: 2