0

I am creating a simple physics engine. Based on some prior vector calculus knowledge I wrote this code right here that takes the x and y components of an instantaneous direction vector "u" and the x and y components of the vector that is the line that the ball collides with "v" and returns a double 'theta' that is the angle between the incoming ball and the line.

private double computeAngle(double uXComponent, double uYComponent, 
        double vXcomponent, double vYComponent) {
    return Math.acos( ( (uXComponent * uYComponent) + (uYComponent * vYComponent) ) / ( Math.sqrt( (uXComponent * uXComponent) + (uYComponent * uYComponent) ) * Math.sqrt( (vXcomponent * vXcomponent) + (vYComponent * vYComponent) ) ) );
}

The program goes on to use this code to determine the new velocity components.

xVelocity *= Math.cos(theta);
yVelocity *= Math.sin(theta);

However if the line is flat i.e v=<500, 0> and the ball is moving in a simple parabolic curve and bouncing across the line the very first bounce is always straight up(xVelocity very near 0). Essentially the value for theta is extremely close to pi/2 (closer than is really should be).

I am sure there is a better way to do this potentially by using dot product. Can anyone help?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
alltrue
  • 585
  • 4
  • 5
  • 1
    For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example) or [SSCCE](http://www.sscce.org/) (Short, Self Contained, Correct Example). – Andrew Thompson Dec 22 '14 at 08:54
  • See also the approach cited [here](http://stackoverflow.com/a/25306319/230513). – trashgod Dec 22 '14 at 12:42

2 Answers2

0

Collisions essentially come down to momentum and elasticity. However, it's entirely possible to ignore elasticity if you want to. There's a number of resources to learn more about conservation of momentum, including this site where there's lecture notes. (Full disclosure, I'm paraphrasing that right now, so go have a read).

An object with mass m1 moving at velocity v1, which collides with another object with mass m2 and velocity v2 at the angle theta can be modeled as having collided in these equations.

m1*v1 + m2*v2*cos(theta) = (m1 + m2) * v3 * cos(phi) //This is for the x axis
m1*v1 + m2*v2*sin(theta) = (m1 + m2) * v3 * sin(phi) //This is for the y axis

In these equations, v3 is the final velocity of the resultant mass and phi is the resultant angle of travel. Note that this is a completely inelastic collision, so the two object form into one.

This SO answer talks about how to calculate the bounce angle off a wall. Essentially; given a velocity that collides with an axis-aligned wall, multiply the given coordinate by -1. Given that I'd just be copying verbatim at this point, I'll just say follow the link, and if that works, then this question is a duplicate.

Community
  • 1
  • 1
Yann
  • 978
  • 2
  • 12
  • 31
  • If I use the first equations for a ball bouncing off a static wall intuition would say make the wall mass infinite and the velocity zero. That leaves you with an indeterminate form (infinity * 0). As for the second linked response, that solution only works for axis aligned walls as you mentioned. I gave an example of an axis aligned wall just for clarity of my problem. I am concerned that for any collision and angle of my wall if the angle is near 90 degrees it is rounded too much. – alltrue Dec 24 '14 at 01:59
0

The error in my code was a simple logic error. The formula for the angle between two vectors is formula for angle between vectors

My code was

Math.acos( ( (uXComponent * uYComponent) + (uYComponent * vYComponent) ) / ( Math.sqrt( (uXComponent * uXComponent) + (uYComponent * uYComponent) ) * Math.sqrt( (vXcomponent * vXcomponent) + (vYComponent * vYComponent) ) )

and it should have been

Math.acos( ( (uXComponent * vXComponent) + (uYComponent * vYComponent) ) / ( Math.sqrt( (uXComponent * uXComponent) + (uYComponent * uYComponent) ) * Math.sqrt( (vXComponent * vXComponent) + (vYComponent * vYComponent) ) )

(In the dot product of the vectors I needed to correct the multiplication of the x components of both the v and u vectors)

alltrue
  • 585
  • 4
  • 5