Reflection problem

HI folks. I’m having a blonde moment over vector reflections, I’ve battled with this before and stumbled, but this time I have to get it working. I’m sure I’m missing something simple, but it’s eluding me.

I need to get the reflected vector of a moving object against a static. The angle of attack could be anything from 0 to 360’

So I have: A and B which are the two objects with position and velocity vectors, and this bit of testing code. In the following case B is stationary.

dim N As Vector2 = Vector2.Normlaize(A.Position-B.Position) '// Normal between centres.
A.Velocity = Vector2.Reflect(A.Velocity, N)

This reflects vertically perfectly, but doesn’t reflect horizontally. I don’t understand how else I’m meant to present the Normal.

Which bit of the equation am I missing?

Thanks folks.

PS, I will get around to answering all your helpful replies soon, life has been complicated!

A. Position - B. Position gives a direction, not a normal.
I’ve don’t see how a normal can be created from 2 points. It is usually perpendicular to a plane given at least a 3 point.
Normalize gives the vector’s coordinates between 0 and 1, it does not give a normal:

In your case the normal is the direction, thus always reflecting on the opposite of the direction between the 2 points

No that parts right the surface plane is derived from the normal given to the reflect function and a normal in graphics refers to a surface normal of a plane polygon or vertice.
This also somewhat derives from optics.


Provided that what he wants is a reflection vector and not a intercept formula.

if you have two vectors ObjectPosition and TargetPosition then…
The target - position gives the direction to the target. .
Normalizing that changes the 3 element vector into a unit length vector by pythagoras…

x^2+y^2+z^2 = c^2; the square root of c^2 gives c;

the x y z coordinates of the original vector are changed by

x/c, y/c, z/c = the new x y z.

This is simply called a normal because a unit length vector is used as a unit length normal, these new elements multiplyed together xx+yy+z*z produce a result of 1. Because of this these unit length vectors have special properties basically they are akin to sin cos values but for 3d hence they are unit length normalized vectors. Commonly just called normal’s for short but they are properly called unit length vectors, or unit length normal.

You can see one of these familiar properties of a unit length normal by multiplying each element against itself, to find the Acos of x y or z described previous, which yields the ratio of the angle in each dimension to the current coordinate system for example .707, .707, 0 becomes .5 .5 in 2d that’s a diagonal line from 0,0, or a 45 degree angle if you sent that to Math.Atan2 * ToDegrees. (I digress)

The Reflect function is not the same as a Dot product or cross product, the cross product can be used to find a surface plane, 3 points or two normals can also be used to find a surface plane, the reflect function uses one normal to discern the surface plane.

float3 i = lightDir; // incidence normal
float3 i = -normal; // surface normal
float3 lightToSurfaceReflection = float3
        2 * n.x * (n.x * i.x + n.y * i.y + n.z * i.z) - i.x,
        2 * n.y * (n.x * i.x + n.y * i.y + n.z * i.z) - i.y,
        2 * n.z * (n.x * i.x + n.y * i.y + n.z * i.z) - i.z

        // in hlsl this function also exists.
        float3 result = reflect(-i, n);

The reflect vector is also intended to be a unit length vector.

The surface normal is used by the function to calculate the surface or the Plane that is used to find the reflection vector in all three dimensions x y z however in the function above this concept is woven into the math itself.

|______> Surface Normal

The reflection vector is a unit normal.
The surface normal is orthogonal to the surface plane.
The reflection formula will reflect the incidence normal to give a resulting reflection normal.
The incidence normal is in your case the target-position direction normalized.
In the below image the positions of the lines don’t matter to the formula only the normalized directions of them.

keep in mind that a ray may reflect off a surface and continue in its general direction or back towards the original rays emission source.

This is a important thing to keep in mind because at times. One may wish to dot the result vector by the original directional vector that was used to find out if the ray is bouncing away or back towards the source of emmision. If the dot product yeild’s a positive value it is bouncing away if negative its bounce back (if i remember that right). Before you start fliping signs of x or y make sure that the result isn’t already correct even for 2d. In the image of the light the normal and the result we see that the sign of results Y element is not the same sign as the Lights y element sign but the x signs are both positive.

Typically when you insert the vectors to the reflect method you can get different results for special circumstances, by just negating one of the vectors passed in to the reflect function the order of passing and which vector you invert matters as well.

Here is a snippet from my shader i wrote the other day that uses the reflect function.

    // a polygon pixels normal.
    float3 V_normal = normalize(mul(input.Normal, (float3x3)gworld)); //world space normal
    // diffuse theta
    float LtoV_diffuseTheta = saturate(dot(V_normal, -lightDir));
    // specular reflect vector theta and power 
    float3 LtoV_reflectVector = reflect(lightDir, V_normal);
    float LtoE_specularTheta = saturate(dot(cameraForward, -LtoV_reflectVector));
    float specularResult = saturate(pow(LtoE_specularTheta, specularSharpness));

You can see the red as it reflects off the edges from behind as i switch on the lighting visuallization.
The full shader is in this post

Sure, I was just trying to explain that his vector and his normal the way it is calculated are co-linear and why he does not achieve what he was expecting

So my code is correct as the normal of the collision point is 90’ to plane of collision.

In my actual code, for some reason I had decided B-A gave me the vector I wanted, when what I needed was A-B.

Thanks for all the info, this will be invaluable at some point.