views:

192

answers:

2

I'm doing a scene using openGL (a house). I want to do some collision detection, mainly with the walls in the house. I have tried the following code:

// a plane is represented with a normal and a position in space
Vector planeNor(0,0,1);
Vector position(0,0,-10);
Plane p(planeNor,position);

Vector vel(0,0,-1);

double lamda; // this is the intersection point
Vector pNormal; // the normal of the intersection

// this method is from Nehe's Lesson 30
coll= p.TestIntersionPlane(vel,Z,lamda,pNormal); 

glPushMatrix();
glBegin(GL_QUADS);
if(coll)
glColor3f(1,0,0);
else
glColor3f(1,1,1);
glVertex3d(0,0,-10);
glVertex3d(3,0,-10);
glVertex3d(3,3,-10);
glVertex3d(0,3,-10);
glEnd();
glPopMatrix();

Nehe's method:

#define EPSILON 1.0e-8

#define ZERO EPSILON
bool Plane::TestIntersionPlane(const Vector3 & position,const Vector3 & direction, double& lamda, Vector3 & pNormal)
{
    double DotProduct=direction.scalarProduct(normal);          // Dot Product Between Plane Normal And Ray Direction
    double l2;

    // Determine If Ray Parallel To Plane
    if ((DotProduct<ZERO)&&(DotProduct>-ZERO))
        return false;

    l2=(normal.scalarProduct(position))/DotProduct; // Find Distance To Collision Point

    if (l2<-ZERO)                           // Test If Collision Behind Start
        return false;

    pNormal= normal;
    lamda=l2;
    return true;
}

Z is initially (0,0,0) and every time I move the camera towards the plane, I reduce its z component by 0.1 (i.e. Z.z-=0.1 ). I know that the problem is with the vel vector, but I can't figure out what the right value should be. Can anyone please help me?

+2  A: 
Beta
A: 

Thank you for your help.

I looked into the code again and I changed the collision detection method into the following:

//startPoint: the ray's starting point.
//EndPoint: the ray's ending point.
//lamda: the intersection point.
 bool Plane::TestIntersionPlane(const Vector3& startPoint,const Vector3& Endpoint, double& lamda)
    {
        double cosAlpha=Endpoint.scalarProduct(normal); // calculates the angle between the plane's normal and the ray vector.

        // Determine If Ray Parallel To Plane
        if ((cosAlpha<ZERO)&&(cosAlpha>-ZERO))
            return false;
          // delta D is the plane's distance from the origin minus the ray's distance from the origin. 
        double deltaD = distance - startPoint.scalarProduct(normal); //distance is a double representing the plane's distance from the origin.

         lamda= deltaD/cosAlpha;// distance between the plane and the vector

         // if the distance between the ray and the plane is greater than zero then they haven't intersected.
         if(lamda > ZERO)
             return false;

         return true;
    }

This seems to work with all planes except when the ray is too far from the plane. For example if the plane is at z=-10 and the ray's starting point is: 0,0,3 and it's ending point is 0,0,2 then this is detected as a collision but when I move the ray to start(0,0,2) and end(0,0,1) it's not detected as a collision. The math seems correct to me, so I'm not sure how to handle this.

Demi
You don't understand the dot product; try without it. And if a case doesn't seem to work right, try it with pencil and paper. And don't use a global "distance".
Beta