在右侧坐标系中查找相交点射线/三角形

问题描述 投票:-1回答:2

我想得到三角形上线的交点(由向量和原点定义)。我的引擎使用右手坐标系,因此X指向前方,Y指向左侧,Z指向上方。


----编辑----

在Antares的帮助下,我使用以下方法将积分转换为引擎空间:

p0.x = -pt0.y;
p0.y = pt0.z;
p0.z = pt0.x;

但是我不知道如何对方向向量做同样的事情。


我使用this stackoverflow question中的功能,原始海报使用this tutorial

首先,我们寻找从原点到相交点的距离t,以找到其坐标。但是我有一个负的t,当ray在三角形之外时代码返回true。我将其设置在视觉上。当我在三角形中时,它有时返回false。

这里是我用来获取相交点的函数,我已经检查了它是否可以工作,并且具有“经典”值,如原始文章中所述。

float kEpsilon = 0.000001;

V3f crossProduct(V3f point1, V3f point2){

  V3f vector; 

  vector.x = point1.y * point2.z - point2.y * point1.z; 
  vector.y = point2.x * point1.z - point1.x * point2.z; 
  vector.z = point1.x * point2.y - point1.y * point2.x; 

  return vector;
}

float dotProduct(V3f dot1, V3f dot2){

  float dot = dot1.x * dot2.x + dot1.y * dot2.y + dot1.z * dot2.z; 

  return dot;
}

//orig: ray origin, dir: ray direction, Triangle vertices: p0, p1, p2.  
bool rayTriangleIntersect(V3f orig, V3f dir, V3f p0, V3f p1, V3f p2){ 

// compute plane's normal

  V3f p0p1, p0p2;

  p0p1.x = p1.x - p0.x; 
  p0p1.y = p1.y - p0.y; 
  p0p1.z = p1.z - p0.z; 

  p0p2.x = p2.x - p0.x;
  p0p2.y = p2.y - p0.y; 
  p0p2.z = p2.z - p0.z;

  // no need to normalize
  V3f N = crossProduct(p0p1, p0p2); // N 

  // Step 1: finding P

  // check if ray and plane are parallel ?
  float NdotRayDirection = dotProduct(N, dir); // if the result is 0, the function will return the value false (no intersection).

  if (fabs(NdotRayDirection) < kEpsilon){ // almost 0 

      return false; // they are parallel so they don't intersect ! 
  }

  // compute d parameter using equation 2
  float d = dotProduct(N, p0); 

  // compute t (equation P=O+tR P intersection point ray origin O and its direction R)

  float t = -((dotProduct(N, orig) - d) / NdotRayDirection);

  // check if the triangle is in behind the ray
  //if (t < 0){ return false; } // the triangle is behind 

  // compute the intersection point using equation
  V3f P; 

  P.x = orig.x + t * dir.x; 
  P.y = orig.y + t * dir.y; 
  P.z = orig.z + t * dir.z; 


  // Step 2: inside-outside test
  V3f C; // vector perpendicular to triangle's plane 

  // edge 0
  V3f edge0; 

  edge0.x = p1.x - p0.x;
  edge0.y = p1.y - p0.y;
  edge0.z = p1.z - p0.z;

  V3f vp0; 

  vp0.x = P.x - p0.x;
  vp0.y = P.y - p0.y; 
  vp0.z = P.z - p0.z; 

  C = crossProduct(edge0, vp0); 

  if (dotProduct(N, C) < 0) { return false; }// P is on the right side 

  // edge 1
  V3f edge1;

  edge1.x = p2.x - p1.x;
  edge1.y = p2.y - p1.y;
  edge1.z = p2.z - p1.z;

  V3f vp1; 

  vp1.x = P.x - p1.x; 
  vp1.y = P.y - p1.y; 
  vp1.z = P.z - p1.z; 

  C = crossProduct(edge1, vp1); 

  if (dotProduct(N, C) < 0) { return false; } // P is on the right side 

  // edge 2
  V3f edge2;

  edge2.x = p0.x - p2.x;    
  edge2.y = p0.y - p2.y;
  edge2.z = p0.z - p2.z;

  V3f vp2; 

  vp2.x = P.x - p2.x;
  vp2.y = P.y - p2.y;
  vp2.z = P.z - p2.z;

  C = crossProduct(edge2, vp2);

  if (dotProduct(N, C) < 0) { return false; } // P is on the right side; 

  return true; // this ray hits the triangle 
} 

我的问题是我得到电话:-52.603783

交叉点P:[-1143.477295,-1053.412842,49.525799]相对于640X480纹理,这给了我uv点:[-658,41]。

可能是因为我的引擎使用Z指向上方?

graphics 3d geometry computational-geometry intersection
2个回答
0
投票

我的引擎使用右手坐标系,所以X指向前方,Y指向左侧,Z指向上方。

您对右手坐标系有一点不正确的想法,请检查https://en.wikipedia.org/wiki/Cartesian_coordinate_system#In_three_dimensions

顾名思义,X指向右(右手的拇指向右),Y指向上(直的食指),Z(直的中指)指向“向前”(实际上-Z朝前,Z在相机坐标系中向后)。实际上...您的坐标分量在右手边,但是解释为X朝前等,是不寻常的。

[如果您怀疑问题可能出在引擎的坐标系上(可能是OGRE?也许是普通的OpenGL?还是自制的?),那么您需要将点和方向的坐标转换为算法的坐标系。如果我没记错的话,您介绍的算法可以在相机坐标系中工作。当然,您需要将结果相交点转换回您在引擎中使用的解释。要围绕矢量分量的方向(例如Z坐标)旋转,可以将-1乘以实现效果。

编辑:还有一件事:我意识到算法也使用方向向量,而不仅仅是点。如果我没记错的话,组件的重新排列仅适用于点,而不适用于方向。也许您必须与CameraView转换矩阵(或其逆M ^ -1或是转置M ^ T,我不确定)进行矩阵乘法。我在这里不能为您提供帮助,希望您能解决这个问题,也可以尝试一下。

我的问题是我得到电话:-52.603783

相交点P:[-1143.477295,-1053.412842、49.525799]相对于640X480纹理,这给了我uv点:[-658、41]

我认为您认为您的价值观不正确。您希望获得t和UV坐标的哪些值?哪些输入对您来说“正确”?

希望这可以帮助您入门。 GL,HF与您的项目! :)


0
投票

@@ GUNNM:关于您不知道如何处理方向向量的反馈,以下是一些可能对您有用的想法。

© www.soinside.com 2019 - 2024. All rights reserved.