game-physicsphysicskinematics

Evaluating rigid body linear and rotational velocities after collision with a wall


I have a relatively simple case that I'm bending my head around for quite some time already, I'm trying to evaluate by hand (without the use of any libraries) the rotational and linear velocities for a 2d square and a ball after collision with a wall.

Given that:

r - is either radius or side length of the square
X1 - is a vector of initial position for a given rigid body
V1 - is a vector representing initial velocity of a given rigid body
R1 - is an initial rotational velocity of a given rigid body

W1 and W2 - are vectors representing position of a wall ends

C - is a vector representing point of collision

X2 - is a vector representing position for a given rigid body at the moment of contact with the wall 
V2 - is a vector representing resulting velocity of a given rigid body after contact
R2 - is a rotational velocity of a given rigid body after contact

I understand that I might be lacking some parameters such as mass, damping, friction or properties describing the material of the wall but I leave that to the person answering the question since there are different models possible.

I'm in progress with a book "Apress Physics for JavaScript Games Animation and Simulations With HTML5 Canvas" by Dev Ramtal and Adrian Dobre, but this topic is very wide, shredded and sparse. So it's hard to get a simple definitive answer how such collision is being resolved.

Diagram


Solution

  • I have tried to write some pseudocode for the case of a rotating disc colliding with a wall. I hope it helps:

    # unit vector aligned with the wall
    T = W2 - W1
    T = T / norm(T)
    
    # unit vector perpendicular to the wall, pointing towards the moving object and 
    # hence perpendicular to T
    N = [- T[1], T[0]]
    
    # initial position and velocity:
    X1 = [X1[0], X1[1]]
    V1 = [V1[0], V2[1]]
    
    R1  = angular velocity, positive if counter-clock-wise, negative otherwise
    
    t_start = start time of simulation
    t_stop = end time of simulation
    k = friction coefficient, 
        that determines how much angular momentum 
        is converted into linear momentum during collision
    
    t_col = t_start + dot(N, W1 + r*N - X1) / dot(N, V1)
    
    if t_col < t_stop{
       V2 = V1 - 2*dot(v1, n)*n  - k*r*R1*T
       R2 = (1 - k)* R1 
       X_col = X1 + V1*(t_col - t_start)
       X_stop = X_col + V2*(t_stop - t_col)
       C = X_col - r*N
    } else{
       X_stop = X1 + V1*(t_stop - t_start)
    }
    

    This is a python version, I just wanted to make sure there are not too many mistakes...

    import numpy as np
    
    # unit vector aligned with the wall
    W1 = np.array([ -1, 0])
    W2 = np.array([10, 1])
    T = W2 - W1
    T = T / np.linalg.norm(T)
    # unit vector perpendicular to the wall, pointing towards the moving object and 
    # hence perpendicular to T
    N = np.array([- T[1], T[0]])
    # initial position and velocity:
    X1 = np.array([ 0, 5])
    V1 = 0.3 * np.array([ 1, -2])
    #angular velocity, positive if counter-clock-wise, negative otherwise
    R1  = -1.2 
    
    t_start = 0 #start time of simulation
    t_stop = 3 #end time of simulation
    k = 0.7 #friction coefficient, 
        #that determines how much angular momentum 
        #is converted into linear momentum during collision
    r = 0.5 # radius of the disc 
    # time of collision
    t_col = t_start + np.dot(N, W1 + r*N - X1) / np.dot(N, V1)
    
    t_start = 0 #start time of simulation
    t_stop = 8 #end time of simulation
    k = 0.7 #friction coefficient, 
        #that determines how much angular momentum 
        #is converted into linear momentum during collision
    r = 0.5 
    
    t_col = t_start + np.dot(N, W1 + r*N - X1) / np.dot(N, V1)
    
    if t_col < t_stop:
       V2 = V1 - 2*np.dot(V1, N)*N  - k*r*R1*T
       R2 = (1 - k)* R1 
       X_col = X1 + V1*(t_col - t_start)
       X_stop = X_col + V2*(t_stop - t_col)
       C = X_col - r*N
    else:
       X_stop = X1 + V1*(t_stop - t_start)