Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

athlon

Bounce vector

This topic is 6172 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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_Y
if( 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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 vector2d

if( 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!

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Or, without trig...

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

...assuming wall_normal is normalized.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Oops...

That should be:

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

Bye!

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!