Sign in to follow this  
SOS

I need help choosing an angle!

Recommended Posts

So, basically what I'm doing is bouncing something off a wall. I treat the wall and the incoming vlocity as vectors to find the resulting velocity. Works well, except one little thing... I can either add the angle-between-wall-and-first-vector or I can subtract it. If the first vector is on "one side" of the wall, then one way works. If on the other side, the other sign works... (The direction of the wall vector in relation to the first vector? Something like that...) However, I found no clear piece of info that tells me which sign I should use for a given pair of vectors. Here is the code I use:
Vector2 v = GetV(); // First vector (green on images).
Vector2 Wall = GetWall(); // Wall as a vector.

float cosa = Vector2.Dot(v, Wall) / v.Length() / Wall.Length();

float angle = (float)Math.Acos(cosa);

Matrix mat = Matrix.RotationZ((float)Math.PI + 2 * angle);
Vector w1 = Vector2.TransformCoordinate(v, mat);

mat = Matrix.RotationZ((float)Math.PI - 2 * angle);
Vector w2 = Vector2.TransformCoordinate(v, mat);
So... when do I use w1 and when w2? Image 1 (blue aka w1 is correct here): Image 2 (red aka w2 is correct here):

Share this post


Link to post
Share on other sites
Assuming "Wall" represents the normal of the wall, and "Ray" is the normalized ray vector (the green one):

float Cos = Ray dot Wall;
vector Bounce = Wall * Cos;

// METHOD #1: Remove the part of the ray that goes towards the wall:
Ray -= Bounce;

// METHOD #2: Make the ray bounce off the wall (this replaces the Method 1 code)
Ray -= 2 * Bounce;



The left image is the problem that needs to be fixed. The middle shows "Method 1" in action. The right shows "Method 2".

Share this post


Link to post
Share on other sites
This is one of the ugly things about Angles that makes me avoid using them...
It is better to got with a pure vector approach.

Here is a better and coputationally cheaper way to do the reflection:
Ascii Art!



in out
\ /
\ N /
\ | /
\ | /
\ | /
\|/
______________
wall

First we have the wall, with its normal-N and the 'in' vector
and I have also drawn the desired 'out' vector, which is the reflection of In across N



in
\
\....N
A \ |
\ |
\ |
\|
_______________

notice the dotted line, if we scale 'in' to be the same height as N (from the wall) we get this new vector call it 'A'


N
| | \A
| | A N
\ |
\ |
\ |
\|
_______________

Now notice, if we do some vector addition, A+N+N+A gives us a big zig-zag path. but what does it add up to?



N
| | \A
| | A N B
\ | /
\ | /
\ | /
\|/
_______________


We end up with a new vector, call it 'B', which is the exact reflection of 'A' across the Normal N

all you need to do now, is scale B to be the same length as the original 'in' vector, and you have your reflected velocity.

AUUGH, sorry, the last 2 diagrams JUST WONT FORMAT properly for some reason, I'm guessing that the input form for this forum is messing them....
at any rate, from the first 2 and the math A+N+N+A = B = outvector should be adequate if you draw it yourself on paper

Anyway, Im Sure that other people here recognize the method I was trying to illustrate with the ascii art, its a very common method, standard on some game job interviews
I invite anyone else to post some real diagrams to explain it.

[Edited by - haphazardlynamed on March 7, 2006 12:01:19 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Basically the the bouncing off a wall is reflecting the component of the input vector which is perpendicular to the wall.

If the velocity is v, and the wall's normal is n, you just project v onto n to find the component of v which is in the direction of n. Assuming n is a unit vector, this projection is simply:

n*(v dot n)

Subtracting this amount from the original vector would give us the component of the original vector which is parallel to the wall (as shown in the middle of the diagram the previous poster made). Subtracting it again would give us the vector where this component was completely reflected (as shown in the right part of the diagram). So what you want to do is:

v - 2*n*(v dot n)

This is the general formula for a reflection about an axis. Easier to use than angles.

If n is not a unit vector, you can use:

v - 2*n*(v dot n)/(n dot n)

If you wanted to keep using your method with angles, you could use the sign of the cross product of the vectors. But this way is slower, more complicated, and only works in two dimensions, while working directly with the vectors avoids the trigonometry and works in three dimensions too.

Share this post


Link to post
Share on other sites
Many thanks to all!

Yeah, I hate angles too because of things like this. I just couldn't think of a vector approach. Woohoo, many thanks once more!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this