Значение параметрической постоянной t в пересечении плоскости и луча? - PullRequest
1 голос
/ 23 марта 2019

Я выполняю тест пересечения луча и прямоугольника.Для этого сначала я проверяю, пересекает ли луч плоскость, если это так, то я вижу, лежит ли он в границах прямоугольника.

Ниже приведен код:

float intersectQuad(Ray r, float3 p1, float3 p2, float3 p3, float3 p4, float3* normal)
{
   float3 x1 = p2 - p1;
   float3 x2 = p4 - p1;
   float t;

   float3 n = normalize(cross(x2, x1));
   float denom = dot(n, r.dir); 

    if (denom > 0.00000000001) 
    { 
       float3 p0l0 = normalize(p1 - r.origin); 
       t = dot(p0l0, n) / denom; 

       printf(" %f ", t);

       if( t > 0.000000000001f )
       {
         float3 hitPoint = r.origin + r.dir * t;

         float3 V1 = normalize(p2 - p1);
         float3 V2 = normalize(p3 - p2);
         float3 V3 = normalize(p4 - p3);
         float3 V4 = normalize(p1 - p4);
         float3 V5 = normalize(hitPoint - p1);
         float3 V6 = normalize(hitPoint - p2);
         float3 V7 = normalize(hitPoint - p3);
         float3 V8 = normalize(hitPoint - p4);

         if (dot(V1,V5) < 0.0f) return 0.0f;
         if (dot(V2,V6) < 0.0f) return 0.0f;
         if (dot(V3,V7) < 0.0f) return 0.0f;
         if (dot(V4,V8) < 0.0f) return 0.0f;

         *normal = n;
         return t;
       }
    } 

 return 0.0f; 
}

Насколько я понимаю, значениеt должно быть 0.0f < t < 1.0f, но когда я печатаю значения t, я иногда вижу значения > 1.0f.

Что-то не так в моем коде?

1 Ответ

1 голос
/ 23 марта 2019

Во-первых, если вектор направления луча нормализован для r.origin + r.direction*t, тогда t - это расстояние от начала координат до hitPoint.Это расстояние может иметь любое значение.

Во-вторых, я бы изменил тип возвращаемого значения на bool, чтобы избежать арифметики с плавающей запятой, чтобы снова сравнить результат с 0.0f в области вызова функции.

В-третьих, скорее для личного вкуса, переформатируйте код следующим образом, используя технику раннего выхода и отметив const значения, где это возможно.

bool intersectQuad(Ray r, float3 p1, float3 p2, float3 p3, float3 p4, float3* outNormal, float* outT)
{
   const float3 x1 = p2 - p1;
   const float3 x2 = p4 - p1;
   const float3 n = normalize(cross(x2, x1));
   const float denom = dot(n, r.dir); 

   if (denom < 0.00000000001) return false;

   const float3 p0l0 = normalize(p1 - r.origin); 
   const float t = dot(p0l0, n) / denom; 

   printf(" %f ", t);

   if( t < 0.000000000001f ) return false;

   const float3 hitPoint = r.origin + r.dir * t;

   const float3 V1 = normalize(p2 - p1);
   const float3 V2 = normalize(p3 - p2);
   const float3 V3 = normalize(p4 - p3);
   const float3 V4 = normalize(p1 - p4);
   const float3 V5 = normalize(hitPoint - p1);
   const float3 V6 = normalize(hitPoint - p2);
   const float3 V7 = normalize(hitPoint - p3);
   const float3 V8 = normalize(hitPoint - p4);

   if (dot(V1,V5) < 0.0f) return false;
   if (dot(V2,V6) < 0.0f) return false;
   if (dot(V3,V7) < 0.0f) return false;
   if (dot(V4,V8) < 0.0f) return false;

   *outNormal = n;
   *outT = t;
   return true;
}
...