public IntrPlane3Plane3(Plane3d p0, Plane3d p1) { plane0 = p0; plane1 = p1; }
public IntrLine3Plane3(Line3d l, Plane3d p) { line = l; plane = p; }
public bool Find() { if (Result != IntersectionResult.NotComputed) { return(Result != g3.IntersectionResult.NoIntersection); } // in this code the results get initialized in subroutines, so we // set the defautl value here... Result = IntersectionResult.NoIntersection; int i, iM, iP; // Get the plane of triangle0. Plane3d plane0 = new Plane3d(triangle0.V0, triangle0.V1, triangle0.V2); // Compute the signed distances of triangle1 vertices to plane0. Use // an epsilon-thick plane test. int pos1, neg1, zero1; Index3i sign1; Vector3d dist1; TrianglePlaneRelations(ref triangle1, ref plane0, out dist1, out sign1, out pos1, out neg1, out zero1); if (pos1 == 3 || neg1 == 3) { // Triangle1 is fully on one side of plane0. return(false); } if (zero1 == 3) { // Triangle1 is contained by plane0. if (ReportCoplanarIntersection) { return(GetCoplanarIntersection(ref plane0, ref triangle0, ref triangle1)); } return(false); } // Check for grazing contact between triangle1 and plane0. if (pos1 == 0 || neg1 == 0) { if (zero1 == 2) { // An edge of triangle1 is in plane0. for (i = 0; i < 3; ++i) { if (sign1[i] != 0) { iM = (i + 2) % 3; iP = (i + 1) % 3; return(IntersectsSegment(ref plane0, ref triangle0, triangle1[iM], triangle1[iP])); } } } else // zero1 == 1 // A vertex of triangle1 is in plane0. { for (i = 0; i < 3; ++i) { if (sign1[i] == 0) { return(ContainsPoint(ref triangle0, ref plane0, triangle1[i])); } } } } // At this point, triangle1 tranversely intersects plane 0. Compute the // line segment of intersection. Then test for intersection between this // segment and triangle 0. double t; Vector3d intr0, intr1; if (zero1 == 0) { int iSign = (pos1 == 1 ? +1 : -1); for (i = 0; i < 3; ++i) { if (sign1[i] == iSign) { iM = (i + 2) % 3; iP = (i + 1) % 3; t = dist1[i] / (dist1[i] - dist1[iM]); intr0 = triangle1[i] + t * (triangle1[iM] - triangle1[i]); t = dist1[i] / (dist1[i] - dist1[iP]); intr1 = triangle1[i] + t * (triangle1[iP] - triangle1[i]); return(IntersectsSegment(ref plane0, ref triangle0, intr0, intr1)); } } } // zero1 == 1 for (i = 0; i < 3; ++i) { if (sign1[i] == 0) { iM = (i + 2) % 3; iP = (i + 1) % 3; t = dist1[iM] / (dist1[iM] - dist1[iP]); intr0 = triangle1[iM] + t * (triangle1[iP] - triangle1[iM]); return(IntersectsSegment(ref plane0, ref triangle0, triangle1[i], intr0)); } } // should never get here... Debug.Assert(false); return(false); }
bool GetCoplanarIntersection(ref Plane3d plane, ref Triangle3d tri0, ref Triangle3d tri1) { // Project triangles onto coordinate plane most aligned with plane // normal. int maxNormal = 0; double fmax = Math.Abs(plane.Normal.x); double absMax = Math.Abs(plane.Normal.y); if (absMax > fmax) { maxNormal = 1; fmax = absMax; } absMax = Math.Abs(plane.Normal.z); if (absMax > fmax) { maxNormal = 2; } Triangle2d projTri0 = new Triangle2d(), projTri1 = new Triangle2d(); int i; if (maxNormal == 0) { // Project onto yz-plane. for (i = 0; i < 3; ++i) { projTri0[i] = tri0[i].yz; projTri1[i] = tri1[i].yz; } } else if (maxNormal == 1) { // Project onto xz-plane. for (i = 0; i < 3; ++i) { projTri0[i] = tri0[i].xz; projTri1[i] = tri1[i].xz; } } else { // Project onto xy-plane. for (i = 0; i < 3; ++i) { projTri0[i] = tri0[i].xy; projTri1[i] = tri1[i].xy; } } // 2D triangle intersection routines require counterclockwise ordering. Vector2d save; Vector2d edge0 = projTri0[1] - projTri0[0]; Vector2d edge1 = projTri0[2] - projTri0[0]; if (edge0.DotPerp(edge1) < (double)0) { // Triangle is clockwise, reorder it. save = projTri0[1]; projTri0[1] = projTri0[2]; projTri0[2] = save; } edge0 = projTri1[1] - projTri1[0]; edge1 = projTri1[2] - projTri1[0]; if (edge0.DotPerp(edge1) < (double)0) { // Triangle is clockwise, reorder it. save = projTri1[1]; projTri1[1] = projTri1[2]; projTri1[2] = save; } IntrTriangle2Triangle2 intr = new IntrTriangle2Triangle2(projTri0, projTri1); if (!intr.Find()) { return(false); } PolygonPoints = new Vector3d[intr.Quantity]; // Map 2D intersections back to the 3D triangle space. Quantity = intr.Quantity; if (maxNormal == 0) { double invNX = ((double)1) / plane.Normal.x; for (i = 0; i < Quantity; i++) { double y = intr.Points[i].x; double z = intr.Points[i].y; double x = invNX * (plane.Constant - plane.Normal.y * y - plane.Normal.z * z); PolygonPoints[i] = new Vector3d(x, y, z); } } else if (maxNormal == 1) { double invNY = ((double)1) / plane.Normal.y; for (i = 0; i < Quantity; i++) { double x = intr.Points[i].x; double z = intr.Points[i].y; double y = invNY * (plane.Constant - plane.Normal.x * x - plane.Normal.z * z); PolygonPoints[i] = new Vector3d(x, y, z); } } else { double invNZ = ((double)1) / plane.Normal.z; for (i = 0; i < Quantity; i++) { double x = intr.Points[i].x; double y = intr.Points[i].y; double z = invNZ * (plane.Constant - plane.Normal.x * x - plane.Normal.y * y); PolygonPoints[i] = new Vector3d(x, y, z); } } Result = IntersectionResult.Intersects; Type = IntersectionType.Polygon; return(true); }
bool IntersectsSegment(ref Plane3d plane, ref Triangle3d triangle, Vector3d end0, Vector3d end1) { // Compute the 2D representations of the triangle vertices and the // segment endpoints relative to the plane of the triangle. Then // compute the intersection in the 2D space. // Project the triangle and segment onto the coordinate plane most // aligned with the plane normal. int maxNormal = 0; double fmax = Math.Abs(plane.Normal.x); double absMax = Math.Abs(plane.Normal.y); if (absMax > fmax) { maxNormal = 1; fmax = absMax; } absMax = Math.Abs(plane.Normal.z); if (absMax > fmax) { maxNormal = 2; } Triangle2d projTri = new Triangle2d(); Vector2d projEnd0 = Vector2d.Zero, projEnd1 = Vector2d.Zero; int i; if (maxNormal == 0) { // Project onto yz-plane. for (i = 0; i < 3; ++i) { projTri[i] = triangle[i].yz; projEnd0.x = end0.y; projEnd0.y = end0.z; projEnd1.x = end1.y; projEnd1.y = end1.z; } } else if (maxNormal == 1) { // Project onto xz-plane. for (i = 0; i < 3; ++i) { projTri[i] = triangle[i].xz; projEnd0.x = end0.x; projEnd0.y = end0.z; projEnd1.x = end1.x; projEnd1.y = end1.z; } } else { // Project onto xy-plane. for (i = 0; i < 3; ++i) { projTri[i] = triangle[i].xy; projEnd0.x = end0.x; projEnd0.y = end0.y; projEnd1.x = end1.x; projEnd1.y = end1.y; } } Segment2d projSeg = new Segment2d(projEnd0, projEnd1); IntrSegment2Triangle2 calc = new IntrSegment2Triangle2(projSeg, projTri); if (!calc.Find()) { return(false); } Vector2dTuple2 intr = new Vector2dTuple2(); if (calc.Type == IntersectionType.Segment) { Result = IntersectionResult.Intersects; Type = IntersectionType.Segment; Quantity = 2; intr.V0 = calc.Point0; intr.V1 = calc.Point1; } else { Debug.Assert(calc.Type == IntersectionType.Point); //"Intersection must be a point\n"; Result = IntersectionResult.Intersects; Type = IntersectionType.Point; Quantity = 1; intr.V0 = calc.Point0; } // Unproject the segment of intersection. if (maxNormal == 0) { double invNX = ((double)1) / plane.Normal.x; for (i = 0; i < Quantity; ++i) { double y = intr[i].x; double z = intr[i].y; double x = invNX * (plane.Constant - plane.Normal.y * y - plane.Normal.z * z); Points[i] = new Vector3d(x, y, z); } } else if (maxNormal == 1) { double invNY = ((double)1) / plane.Normal.y; for (i = 0; i < Quantity; ++i) { double x = intr[i].x; double z = intr[i].y; double y = invNY * (plane.Constant - plane.Normal.x * x - plane.Normal.z * z); Points[i] = new Vector3d(x, y, z); } } else { double invNZ = ((double)1) / plane.Normal.z; for (i = 0; i < Quantity; ++i) { double x = intr[i].x; double y = intr[i].y; double z = invNZ * (plane.Constant - plane.Normal.x * x - plane.Normal.y * y); Points[i] = new Vector3d(x, y, z); } } return(true); }
public IntrRay3Plane3(Ray3d r, Plane3d p) { ray = r; plane = p; }