Bounce vector

Started by
7 comments, last by athlon 22 years, 6 months ago
Hi! I want to make a program that bounces a ball against walls in 2D, but i''m having trouble finding the direction a ball should head to after it has collided with a wall. All I have is the direction vector of the ball (and it''s speed and position of course) and the position of the wall (and it''s normal) Could you please tell me what I must to do make this work? please
Advertisement
2D vector, vertical and horizontal "planes" of collision (edges of screen): flip sign of either x- or y-axis component of velocity.
// our velocity is in the vector2d v// our position is in the vector2d p// screen limits are SC_MIN_X, SC_MIN_Y, SC_MAX_X, SC_MAX_Yif( p.x > SC_MAX_X ){  p.x = SC_MAX_X;  v.x = -v.x;}if( p.x < SC_MIN_X ){  p.x = SC_MIN_X  v.x = -v.x;}if( p.y > SC_MAX_Y ){  p.y = SC_MAX_Y;  v.y = -v.y;}if( p.y < SC_MIN_Y ){  p.y = SC_MIN_Y;  v.y = -v.y;} 

This is extremely simplistic and not the most elegant/efficient solution, but it clearly demonstrates the underlying principles.
Thanks for the reply Oluseyi, but that does not completely solve
the problem because the walls could be at any angle not only
parallel with the edges of the screen.
Aha, the general solution. Bounce in a frictionless medium is just like reflection of light from a shiny surface: the angle of incidence is equal to the angle of reflection. The cosine of the angle between two vectors (the surface we bounce off can be considered a vector if viewed from the side) is equivalent to the dot product of the two vectors divided by the product of the magnitude of the two vectors. ie
 A * B = |A||B|cos(ab)(where ab is the angle between A and B)=> ab cos-1( (A * B) / |A||B| ) 

So the only issue is orienting the resulting vector.
  // the current velocity is in the vector2d v - the direction vector// the current position is in the vector2d p// the collision boundary is in the vector2d b// the dotp2() function calculates the dot product of 2 vector2d''s// the mag2d function calculates the magnitude of a vector2dif( Condition_for_collision ){  float dp = dotp2( v, b );  float mag = mag2(v) * mag2(b);  float ang = acos( dp/mag );  v.x = b.x * sin(ang) - b.y * cos(ang);  v.y = b.x * cos(ang) + b.y * sin9ang);}  

Two things:
1.) We calculate the inverse cosine and then the cosine of the inverse cosine, which is redundant. cos(acos(x)) = x. Also, cos(x) = sin( x + PI/2). So we can replace all those trig calculations:
float sine = dp/mag + PI/2;float cosine = dp/mag;v.x = b.x * sine - b.y * cosine;v.y = b.x * cosine + b.y * sine; 


2.) My trig rotation is rusty, so check those coefficients!
Still a few more questions.

What is a collision boundary (Is it the normal of the wall?)
Which vectors, if any have to be normalized?

And now a very stupid on:
Is vector magnitude the same as vector length?
What I called the collision boundary is just the surface the ball collides with, or a vector parallel to it. You don''t explicitly need to normalize either of the vectors, but if you do then you can omit the division of dp by mag (since mag2(v) and mag2(b) will both be 1).

And yes, vector magnitude and length are synonyms.
Or, without trig...

new_vector=old_vector-wall_normal.dot( old_vector )*2;

...assuming wall_normal is normalized.

in the above posting... you say...
new_vector=old_vector-wall_normal.dot( old_vector )*2;

I assume the last term, is a dot product? a dot product returns a scalar... and old_vector is a vector. How do you subtract a scalar from a vector? Not at all I suggest.
Oops...

That should be:

new_vector=old_vector-wall_normal*wall_normal.dot( old_vector )*2;

Bye!

This topic is closed to new replies.

Advertisement