Determining the intersection of a triangle and a plane

随声附和 提交于 2019-12-20 08:59:52

问题


I have a single triangle and a plane (in 3 dimensional space), How would I calculate the line segment where the two cross, if there is no crossing then I need to detect this case.

The end result I'm looking for is two 3 dimensional vectors, which define the start and end points of the line segment.

To help you out a little, I have already calculated the intersection ray between the plane of the face, and the plane, I simply need to find the endpoints to clip that ray into a line segment.

For those who like reading things in code:

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

回答1:


Here's some suggested pseudo code. Simple version first, more robust version later (just to help separate the principle from the neuances). Simple version:

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

Now adding some robustness:
[Edit: Added explicit consideration for the case of a single vertex on the plane]

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 
}

Hopefully that gives an idea, but there are still quite a few potential optimizations. If, for example, you're calculating these intersections for every triangle in a large mesh, you might calculate and cache the DistanceFromPlane once per vertex, and just retrieve it for every edge the vertex participates in. There can be more advanced caching too, depending on your scenario and data representation.




回答2:


Plug the 3 points into the plane equation (defined by the 4 parameters you listed a,b,c,d) and determine which pairs are on opposite sides of the plane.

Given the plane equation:

Ax + By + Cz + D = 0

where A,B,C is the normal (unit length) and D is the distance to origin IIRC, you plug in points (x,y,z) and see if this result is positive or negative. It will be zero for points on the plane, and the sign will tell you which side a point is on when the result is not 0. So pick pairs of points on opposite sides (there will be at most 2) and compute the intersection of those 2 segments with the plane using a standard ray/plane intersection formula which escapes me right now. Those will be the 2 points that form the segment you seek.

EDIT Come to think of it, the values you get from plugging the points into the plane equation should be useful for interpolating between pairs of points to get the intersection of segments with the plane.

Len Fn = Axn + Byn + C*zn + D be the result of plugging in point n. Then suppose F1 = -4 and F2 = 8. So points P1 and P2 are on opposite sides of the plane. We will also have P = P1*2/3 + P2*1/3 is the point of intersection of the segment from P1 to P2 with the plane. Generalizing this into a proper formula is left as an exorcise.




回答3:


Find the intersection of each line segment bounding the triangle with the plane. Merge identical points, then

  • if 0 intersections exist, there is no intersection
  • if 1 intersection exists (i.e. you found two but they were identical to within tolerance) you have a point of the triangle just touching the plane
  • if 2 points then the line segment between them is the intersection

next step, search SO for line-segment to plane intersection algorithms (or just use the one provided by your framework)...




回答4:


It depends a bit on what libraries you have. I have created my own geometry library which can calculate the intersection of a line with a plane. In this case calculate the three points of intersection of the three edges of the triangle and then calculate which of them lie between vertices. This could be 0 (no intersection), or 2 which is the case you want. (There are special cases where the two points are coincident - a point of the triangle).



来源:https://stackoverflow.com/questions/3142469/determining-the-intersection-of-a-triangle-and-a-plane

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!