Mar*_*tin 19 language-agnostic math geometry
我有一个三角形和一个平面(在三维空间中),我如何计算两个交叉的线段,如果没有交叉,那么我需要检测这种情况.
我正在寻找的最终结果是两个三维向量,它们定义了线段的起点和终点.
为了帮助你,我已经计算了面的平面和平面之间的交叉射线,我只需要找到端点来将该光线剪切成线段.
对于喜欢在代码中阅读内容的人:
Face face;        //a face, defined by 3 points
Plane plane;      //a plane, defined by a normal vector and a distance
Ray intersection; //a ray, defined by a point and a direction, initialised to the intersection of the face plane and the face
Segment s = CalculateSegment(face, plane, intersection); //this method needs defining
Ofe*_*lon 18
这是一些建议的伪代码.首先是简单版本,后面是更强大的版本(只是为了帮助将原理与联盟分开).简单版本:
// Assume the plane is given as the equation dot(N,X) + d = 0, where N is a (not
// neccessarily normalized) plane normal, and d is a scalar. Any way the plane is given -
// DistFromPlane should just let the input vector into the plane equation.
vector3d planeN;
float planeD;
float DistFromPlane( vector3d P)
{
// if N is not normalized this is *not* really the distance, 
// but the computations work just the same.
    return dot(planeN,P) + planeD;
}
bool GetSegmentPlaneIntersection( vector3d P1, vector3d P2, vector3d& outP)
{
  float d1 = DistFromPlane(P1),
        d2 = DistFromPlane(P2);
  if (d1*d2 > 0)  // points on the same side of plane
     return false;
  float t = d1 / (d1 - d2); // 'time' of intersection point on the segment
  outP = P1 + t * (P2 - P1);
  return true;
}
void TrianglePlaneIntersection(vector3d triA, vector3d triB, vector3d triC,
                               vector3dArray& outSegTips)
{
   vector3d IntersectionPoint;
   if( GetSegmentPlaneIntersection( triA, triB, IntersectionPoint))
     outSegTips.Add(IntersectionPoint);
   if( GetSegmentPlaneIntersection( triB, triC, IntersectionPoint))
     outSegTips.Add(IntersectionPoint);
   if( GetSegmentPlaneIntersection( triC, triA, IntersectionPoint))
     outSegTips.Add(IntersectionPoint);
}
现在添加一些鲁棒性:
[编辑:添加了对平面上单个顶点的明确考虑]
vector3d planeN;
 float planeD;
float DistFromPlane( vector3d P)
{
    return dot(planeN,P) + planeD;
}
void GetSegmentPlaneIntersection( vector3d P1, vector3d P2, vector3dArray& outSegTips)
{
  float d1 = DistFromPlane(P1),
        d2 = DistFromPlane(P2);
  bool  bP1OnPlane = (abs(d1) < eps),
        bP2OnPlane = (abs(d2) < eps);
  if (bP1OnPlane)
     outSegTips.Add(P1);
  if (bP2OnPlane)
     outSegTips.Add(P2);
  if (bP1OnPlane && bP2OnPlane)
     return;
  if (d1*d2 > eps)  // points on the same side of plane
     return;
  float t = d1 / (d1 - d2); // 'time' of intersection point on the segment
  outSegTips.Add( P1 + t * (P2 - P1) );
}
void TrianglePlaneIntersection(vector3d triA, vector3d triB, vector3d triC,
                               vector3dArray& outSegTips)
{
   GetSegmentPlaneIntersection( triA, triB, outSegTips));
   GetSegmentPlaneIntersection( triB, triC, outSegTips));
   GetSegmentPlaneIntersection( triC, triA, outSegTips));
   RemoveDuplicates(outSegTips);  // not listed here - obvious functionality 
}
希望这能给出一个想法,但仍然有很多潜在的优化.如果,例如,你在一个大型的网状计算这些交叉点的每个三角形,你可能会计算每一次顶点缓存DistanceFromPlane,只是检索它的顶点在每个参与的边缘,可以有更先进的高速缓存过多,取决于您的方案和数据表示.