Deflection from a Surface under any orientation

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Helderash
Posts: 49
Joined: Sun Mar 25, 2007 8:41 pm

Deflection from a Surface under any orientation

Post by Helderash »

Hey folks!

I'm looking to write an algorithm that sets the trajectory of a sphere after collision with a flat polygon (under any orientation), and was wondering if anyone had any suggestions on how to approach the problem. The information I have available is the velocity vector of the sphere prior to collision, and the normal vector of the collision plane.

My code currently looks like this:

Code: Select all

    if(velocity.dotProduct(n)>-0.000001)
    {
        if(n.X!=0)
            velocity.X = velHack.X * n.X;
        if(n.Y!=0)
            velocity.Y = velHack.Y * n.Y;
        if(n.Z!=0)
            velocity.Z = velHack.Z * n.Z;
    }
The reason for the if statement is that im dealing with non-instantaneous collisions (for deformation). The variable velHack stores the velocity prior to collision multiplied by the coefficient of restitution (my cheap way of calculating the deflection velocity). This method works fine provided the collision polygons are parallel to either the x, y or z axis (meaning the normal values are 1, 0, or -1). However, is there a mathematical way of dealing with this problem when the polygon is not axis aligned?

I believe the direction of the resultant velocity vector needs to be equal but opposite to the angle (i.e. the other side) between the incident velocity vector the normal vector of the polygon.

Thanks for the help!

James.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

It sounds like you are trying to get a reflection vector. If you have a surface normal and the world velocity of sphere, you can easily calculate the reflected velocity vector.

Code: Select all

// expects that plane.Normal is already normalized. returns false if v is
// not pointing toward the front face of the plane. v will be reflection
// vector
bool pland3df_reflectVector(const core::plane3df& p, core::vector3df& v)
{
  // get the amount of v that is in the direction of the normal.
  const core::vector3df v_dot_n = v.dotProduct(p.Normal);
  if (! (v_dot_n < 0.f))
    return false; // v is actually pointing away from plane or parallel to it

  // v_dot_n is negative

  v -= 2 * (p.Normal * v_dot_n);

  return true;
}
If you get the dot product of the plane normal and v, that is the length of the part of v that is in line with the normal. If that number is less than zero, then v is pointing into the plane. If we take that and multiply it by the normal of the plane, you get a vector that represents the component of v that is perpendicular to the plane. if you subtract that twice from v, you will have a reflected vector.

Assume a normal n (0, 1, 0) and a velocity vector v (3, -.5, 0). The value of v_dot_n will be 0*3 + 1*-.5 + 0*0 which is -.5. You multiply that by the normal and you get (0, -.5, 0). Multiply that by 2 and you get (0, -1, 0). Finally subtract that from the original v, you get (3, -.5, 0) - (0, -1, 0) which is (3, .5, 0). The part of the velocity vector pointing into the plane is now reversed.

Travis
Helderash
Posts: 49
Joined: Sun Mar 25, 2007 8:41 pm

Post by Helderash »

Hi Vitek,

That is exactly what I was looking for, thankyou very much for your help! Currently writing up a presentation for Tuesday, but hopefully I'll get a chance to implement it Tuesday evening. I'll let you know how things get on.

Thankyou once more, that's been a real help!
Post Reply