Проблема обнаружения столкновений (пересечение с плоскостью) - PullRequest
1 голос
/ 30 апреля 2010

Я делаю сцену, используя openGL (дом). Я хочу сделать некоторые обнаружения столкновений, в основном со стенами в доме. Я пробовал следующий код:

// 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();

Метод Нехе:

#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 изначально равен (0,0,0), и каждый раз, когда я перемещаю камеру к плоскости, я уменьшаю ее компоненту z на 0,1 (то есть Z.z- = 0,1). Я знаю, что проблема с вектором vel, но я не могу понять, какое должно быть правильное значение. Может кто-нибудь помочь мне?

Ответы [ 2 ]

2 голосов
/ 30 апреля 2010
  1. Вы передаете «vel» (я полагаю, это скорость движущейся вещи) как «Положение», а Z (я полагаю, это положение) как «Направление».
  2. Ваш расчет "Расстояние до точки столкновения" не имеет смысла. Он вообще не учитывает положение плоскости (или, может быть, делает, если переменные названы неправильно).
  3. Вы определяете pNormal, но я не вижу смысла в этом. Это должно означать что-то еще?

Почти невозможно заставить что-то подобное работать без понимания математики. Попробуйте более простой вариант теста, возможно, предположив, что плоскость z = 0 и движение по оси z, запустите эту работу и затем по-другому взгляните на общий случай.

0 голосов
/ 01 мая 2010

Спасибо за вашу помощь.

Я снова просмотрел код и изменил метод обнаружения столкновений на следующий:

//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;
    }

Это похоже на работу со всеми плоскостями, за исключением случаев, когда луч находится слишком далеко от плоскости. Например, если плоскость находится в точке z = -10, а начальная точка луча: 0,0,3, а конечная точка - 0,0,2, то это определяется как столкновение, но когда я перемещаю луч в начало (0 , 0,2) и конец (0,0,1) не определяется как столкновение. Математика кажется мне правильной, поэтому я не уверен, как справиться с этим.

...