当射线穿过三角形时,我想在三角形上得到交点。我遵循了在线教程并制作了一个函数,但无法获得正确的交点坐标。

例如,如果我使用射线原点(0,2,-1),射线方向(0,1,0),三角形顶点p0(0,3, 0),p1(-0.5、3,-1),p2(0.5、3,-1)。但是,我得到了交点(0,7,-1),这是不正确的。

感谢您的宝贵时间和帮助。 :-)

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;

  //this part should do the work, but it does not work.
  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
}


谢谢你的帮助。

最佳答案

您得到t = 5并得到(0,7,-1),但t的正确数字为1,原因是您拥有float t = (dotProduct(N, orig) + d) / NdotRayDirection;而正确的代码为float t = -((dotProduct(N, orig) - d) / NdotRayDirection);这有望解决您的问题。

关于c++ - 如何获得交点?射线三角形相交C++,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31178874/

10-11 19:00