# Vector Reflection

## Recommended Posts

ok i have been trying to get my reflection function to work for a while now and i'm having no such luck. i want to be able to input an incident vector and the surface normal and get the reflected vector or the incident vector. i have been using the formula I' = I-2 * dot(N,I) * N; I is the incident vector N is the normal dot() is the dot product does this formula only work for normals that are not parallel to an axis (ie X, Y, or Z axes)? the incident vector was originally along the same axis but in the opposite direction and it went all weird, giving me odd results. should this function work for incident vectors perpendicular and parallel to the normal? also here is my dot product function. its possible there is something wrong here float Dot3(Vector3 vector1, Vector3 vector2) { return (vector1.x * vector2.x) + (vector1.y * vector2.y) + (vector1.z * vector2.z); }

##### Share on other sites
jyk    2094
Quote:
 Original post by adam17ok i have been trying to get my reflection function to work for a while now and i'm having no such luck. i want to be able to input an incident vector and the surface normal and get the reflected vector or the incident vector. i have been using the formula I' = I-2 * dot(N,I) * N;I is the incident vectorN is the normal dot() is the dot productdoes this formula only work for normals that are not parallel to an axis (ie X, Y, or Z axes)? the incident vector was originally along the same axis but in the opposite direction and it went all weird, giving me odd results. should this function work for incident vectors perpendicular and parallel to the normal?also here is my dot product function. its possible there is something wrong herefloat Dot3(Vector3 vector1, Vector3 vector2){ return (vector1.x * vector2.x) + (vector1.y * vector2.y) + (vector1.z * vector2.z);}
Your dot product looks correct, and the reflection equation should work for any orientation of I and N. Keep in mind though that N needs to be unit length.

##### Share on other sites
hmm well im not sure what is going on if those are right. i have a point moving with a velocity of -0.1 on the X axis and -0.1 on the Y axis. when it collides with a plane, the point reflects along the normal. since the normal is 1,0,0, the point travels along the normal.

any ideas

##### Share on other sites
Quote:
 when it collides with a plane, the point reflects along the normal. since the normal is 1,0,0, the point travels along the normal.

The values you present, yield I' = (-.1, .1, 0) which is -clearly- not colinear to N = (1,0,0).
How can the point travel along the normal then?

##### Share on other sites
im not sure what happens. the point travels along the path (-0.1,-0.1, 0) until it collides with the plane. once it bounces off of the wall it then changes its velocity to (0.1, 0, 0).

##### Share on other sites
Then it seems that the result is -somehow- overwritten, right after you've calculated it... What do you get on the debugger?
Have you tried stepping into the heart of the calculations?

Also make sure that your dot product function is exactly as posted above, and the multiplications are indeed component-wise.
There can't be a mistake anywhere else. It's the only thing used there...

##### Share on other sites
ok i think ive narrowed it down. i manually calculated everything. i used the incident vector of (-0.1, -0.1, 0.0) and a normal of (1,0,0). i got (.1414, 0, 0). the normal y and z values limit the reflected angle to only the x-axis. ill show you what i found:

i=<-0.1, -0.1, 0> n=<1, 0, 0>
r = (i-2) * n * dot(i,n)
r = (-1.414, -1.414, 0) * (1, 0, 0) * ((-0.1*1) + (-0.1*0) + (0*0))
r = (-1.414, -1.414, 0) * (1, 0, 0) * -0.1
r = (-1.414, 0, 0) * -0.1
r = (.1414, 0, 0)

there has to be a better reflect equation out there unless i somehow messed this calculation up too.

##### Share on other sites
Rockoon1    104
Quote:
 Original post by adam17i=<-0.1, -0.1, 0> n=<1, 0, 0>r = (i-2) * n * dot(i,n)

Well this is definately wrong. i is a vector, 2 is a scaler. You can't subtract a scaler from a vector :)

Shouldn't it be r = i - (2 * n * dot(i, n)) ...?

##### Share on other sites
w00t!!!!! hell fraking yeah!

that works now! i really appreciate it!

##### Share on other sites
ok now i have a couple of balls bouncing around on the screen. now i want to implement a way for them to bounce off of each other when they collide. unfortunately im not sure on how to go about this. im assuming i can still use the reflect function i have but what do i use as the normal?

##### Share on other sites
jjd    2140
You need the normal of the contact surface between the balls. You can get it (the normal) from the relative position of the center of one ball to the other. Normalize the relative position and there you go (take care with its orientation though).

##### Share on other sites
well im not sure if this is physically correct although it looks right, but i used a basic method of the momentum-collision formula and basically swapped the velocities (i havent implemented masses yet) of the two balls. it looks correct, but im not entirely sure if its right.

##### Share on other sites
If you know the radius of the ball, you can calculate when a collision will happen , place the coords of the balls to where they would be colliding, and they will both go perpendicular to (ball1_pos - ball2_pos) vector. This is assuming that they only are moving in a plane (only 2 coords) and not moving in 3d.

##### Share on other sites
WhardieJones    100
I would think an easy way to reflect against a plane would be to find the component of the vector with respect to the plane's and then negate it. Your formula seems correct.

##### Share on other sites
sweet! god i love this forum. people really know what theyre talking about! i did run into a bit of a problem. occasionally when 2 balls collide they will stick together and start shaking. they only get out of it when another ball collides with them. here is what i have for the collision response:
Vector3 iv = ball[i].vel;Vector3 jv = ball[j].vel;ball[i].vel = reflect(iv, Normalize(iv - jv));ball[j].vel = reflect(jv, Normalize(jv - iv));

i know i need to utilize the radius of the ball somehow to offset the positions. ive tried a few different ways and usually the balls go flying in odd directions and possibly leave the arena.

##### Share on other sites
jyk    2094
Quote:
 Original post by adam17ball[i].vel = reflect(iv, Normalize(iv - jv));ball[j].vel = reflect(jv, Normalize(jv - iv));
Shouldn't the arguments to Normalize() be the balls' positions rather than their velocities? You might try that and see if the behavior improves.

##### Share on other sites
I think the collision responce might be incorrect
you said you are reflecting the velocity of each ball against the plane that separates them?(more or less separate calculations for each ball)

consider the example, ballA is at rest, ballB moves and hits ballA
if you do a simple velocity reflection for each ball,
A stays where it is, since reflection of 0 is still 0
B flips off in some other direction with the same speed

clearly thats not right, A should be affected by the collision and come out with Some velocity, unless it is incredibly massive compared to B

I think you should be swapping the velocity component that is perpedicular to the separating plane between the two balls... (if they have equal mass, dunno how you'd deal with unequal mass situations...)

##### Share on other sites
Quote:
 Shouldn't the arguments to Normalize() be the balls' positions rather than their velocities? You might try that and see if the behavior improves.

i tried changing from normalizing velocities to normalizing the positions and everything goes to hell. any ideas?

##### Share on other sites
given vel, normal -the velocity and surface normal

flipcomponent=projection(vel, normal)
newvel=vel-(2*flipcomponent)

This is essentially what I have in my code...
of course, you will need to have a working vector projection function
it's been a long time since i wrote it for my vector library, so I dont remember the actual projection calculation.. never needed that kind of detail(beauty of abstration) but I belive it involved a dotproduct(a,b)/dotproduct(b,b)

##### Share on other sites
ok i found a little hack that fixed my "sticking" problem. all i did was updated the position with the velocity. it works pretty well right now, although i havent put it through its paces yet. my next step is implementing the mass into the collisions.