# Resultant Vector Algorithm for 2D Collisions

I am making a Pong based game where a puck hits a paddle and bounces off. Both the puck and the paddles are Circles. I came up with an algorithm to calculate the resultant vector of the puck once it meets a paddle. The game seems to function correctly but I'm not entirely sure my algorithm is correct. Here are my variables for the algorithm:

Given:
velocity = the magnitude of the initial velocity of the puck before the collision
x = the x coordinate of the puck
y = the y coordinate of the puck
moveX = the horizontal speed of the puck
moveY = the vertical speed of the puck

otherX = the x coordinate of the paddle
otherY = the y coordinate of the paddle
piece.horizontalMomentum = the horizontal speed of the paddle before it hits the puck
piece.verticalMomentum = the vertical speed of the paddle before it hits the puck

slope = the direction, in radians, of the puck's velocity
distX = the horizontal distance between the center of the puck and the center of the paddle
distY = the vertical distance between the center of the puck and the center of the paddle

Algorithm solves for:
impactAngle = the angle, in radians, of the angle of impact.
newSpeedX = the speed of the resultant vector in the X direction
newSpeedY = the speed of the resultant vector in the Y direction

Here is the code for my algorithm:

int otherX = piece.x;
int otherY = piece.y;
double velocity = Math.sqrt((moveX * moveX) + (moveY * moveY));

double slope = Math.atan(moveX / moveY);
int distX = x - otherX;
int distY = y - otherY;

double impactAngle = Math.atan(distX / distY);

double newAngle = impactAngle + slope;
int newSpeedX = (int)(velocity * Math.sin(newAngle)) + piece.horizontalMomentum;
int newSpeedY = (int)(velocity * Math.cos(newAngle)) + piece.verticalMomentum;


for those who are not program savvy here is it simplified:

velocity = √(moveX² + moveY²)
slope = arctan(moveX / moveY)
distX = x - otherX
distY = y - otherY

impactAngle = arctan(distX / distY)

newAngle = impactAngle + slope
newSpeedX = velocity * sin(newAngle) + piece.horizontalMomentum
newSpeedY = velocity * cos(newAngle) + piece.verticalMomentum


My Question:
Is this algorithm correct? Is there an easier/simpler way to do what I'm trying to do?

## migrated from physics.stackexchange.comMar 29 '12 at 0:28

This question came from our site for active researchers, academics and students of physics.

• In game development, 'it seems to function correctly' is all you need. – Manishearth Mar 25 '12 at 2:01
• I haven't attempted to dissect your code, but...a elastic circle--circle collision is easy looked at in the right way. It's the same old angle of impact equals angle of rebound you get with a circle--plane collision, only you measure relative their common tangent at the point of impact. If you want to include inelastic behavior or spin effect things get rather harder. – dmckee Mar 25 '12 at 3:47
• @dmckee not too much for inelastic, spin behavior makes it evil though(iirc angular impulse and friction come into play) – Manishearth Mar 25 '12 at 5:33
• Possibly related: gamedev.stackexchange.com/questions/3430/… – Tetrad Mar 29 '12 at 16:27

As I said in the comments, for games, all you need is "it seems to function correctly".

I'm not sure if your code is correct (looks a bit off, but I haven't looked at it too closely).

Here's a more efficient formula that avoids trig and square roots:

math formula http://mathbin.net/equations/91525_0.png

Simplifying into components, where:

http://mathbin.net/equations/91527_1.png

http://mathbin.net/equations/91527_2.png

In code:

 int otherX = piece.x;
int otherY = piece.y;
int distX = x - otherX;
int distY = y - otherY;
double dotprod=(distX*moveX+distY*moveY)/(distX*distX+distY*distY)
newSpeedX=2distX*dotprod+moveX
newSpeedY=2distY*dotprod+moveY


## For newAngle

AFAICT, you only need this variable for calculating the velocities, but if you need it for something else as well, you may use this:

newAngle can be calculated by:

newAngle calculation http://mathbin.net/equations/91528_0.png

Simplified,

simplified newAngle calculation http://mathbin.net/equations/91529_0.png

In code:

newAngle=arccos(dotprod*Math.sqrt((distX*distX+distY*distY)/(moveX*moveX+moveY*moveY)))


Or, you could use your old method to calculate newAngle, this one involves an inverse trig function and a square root, while yours involves two inverse trig functions--pretty much the same load on the computer IMO (both functions are solved via power series usually).

• +1 Thank you for the answer, I'm going to use your algorithms to simplify my code, if nothing better comes up when its migrated ill give you the answer – John Mar 25 '12 at 15:43
• @John. No problem.. DavidZaslavsky is going to be inactive for this week, so I asked dmckee to do the migration... Just out of interest, do you need newAngle anywhere else in the code after this collision bit? If so, why? – Manishearth Mar 25 '12 at 15:51
• @Manishhearth i might use it later depending if i want the player to be able to spin the ball, but I'm not sure if I'm going to add that or not. I left it in the question just in case. – John Mar 25 '12 at 15:54
• In that case its better to just use a collision simulating API. The people at gamedev may know a few. (I think Box2D may work, but I'm no expert) – Manishearth Mar 25 '12 at 16:23
• This seems like its not getting migrated, therefore you helped me the most so ill give you the credit for the answer – John Mar 27 '12 at 5:56