seVenVo1d
seVenVo1d

Reputation: 426

Creating a 2D billiard ball game, Ball velocity problem

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

enter image description here

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

Answers (1)

Rob Bricheno
Rob Bricheno

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

Related Questions