/// <summary> /// Testing whether 2 line segments overlapped /// </summary> /// <param name="lineSegment1">First line segment</param> /// <param name="lineSegment2">Second line segment</param> /// <param name="overlappedSegment">The resulting overlapped line segment</param> /// <param name="mode">The enumeration of the result</param> /// <returns></returns> public static bool overlap(LineSegment3D lineSegment1, LineSegment3D lineSegment2, out LineSegment3D overlappedSegment, out LineSegmentOverlapEnum mode) { mode = LineSegmentOverlapEnum.Undefined; overlappedSegment = lineSegment1; // First check whether they have the same lineDirection (absolute: -v = +v for overlap test) if (!Line3D.parallel(lineSegment1.baseLine, lineSegment2.baseLine)) { return(false); } // The lines are parallel, now check whether there is at least one point falls in the segment // Test points in line 2 on line 1 LineSegmentOnSegmentEnum p1l1_s, p2l1_s; LineSegmentOnSegmentEnum p1l2_s, p2l2_s; bool p1l1 = isInSegment(lineSegment1, lineSegment2.startPoint, out p1l1_s); bool p2l1 = isInSegment(lineSegment1, lineSegment2.endPoint, out p2l1_s); if (p1l1 && p2l1) { if ((p1l1_s == p2l1_s && p2l1_s == LineSegmentOnSegmentEnum.InsideSegment) || (p1l1_s == LineSegmentOnSegmentEnum.CoincideEndSegment && p2l1_s == LineSegmentOnSegmentEnum.InsideSegment) || (p1l1_s == LineSegmentOnSegmentEnum.InsideSegment && p2l1_s == LineSegmentOnSegmentEnum.CoincideEndSegment)) { mode = LineSegmentOverlapEnum.SubSegment; } if (p1l1_s == p2l1_s && p1l1_s == LineSegmentOnSegmentEnum.CoincideEndSegment) { mode = LineSegmentOverlapEnum.ExactlyOverlap; } overlappedSegment = lineSegment2; return(true); } else if (p1l1 || p2l1) { if (p1l1_s == LineSegmentOnSegmentEnum.CoincideEndSegment || p2l1_s == LineSegmentOnSegmentEnum.CoincideEndSegment) { mode = LineSegmentOverlapEnum.Touch; // Zero lenth line segments = a point, a valid data if (p1l1) { overlappedSegment = new LineSegment3D(lineSegment2.startPoint, lineSegment2.startPoint); } if (p2l1) { overlappedSegment = new LineSegment3D(lineSegment2.endPoint, lineSegment2.endPoint); } } if (p1l1_s == LineSegmentOnSegmentEnum.InsideSegment || p2l1_s == LineSegmentOnSegmentEnum.InsideSegment) { bool p1l2 = isInSegment(lineSegment2, lineSegment1.startPoint, out p1l2_s); bool p2l2 = isInSegment(lineSegment2, lineSegment1.endPoint, out p2l2_s); if (p1l1_s == LineSegmentOnSegmentEnum.InsideSegment && p1l2_s == LineSegmentOnSegmentEnum.InsideSegment) { overlappedSegment = new LineSegment3D(lineSegment2.startPoint, lineSegment1.startPoint); } if (p2l1_s == LineSegmentOnSegmentEnum.InsideSegment && p1l2_s == LineSegmentOnSegmentEnum.InsideSegment) { overlappedSegment = new LineSegment3D(lineSegment2.endPoint, lineSegment1.startPoint); } if (p1l1_s == LineSegmentOnSegmentEnum.InsideSegment && p2l2_s == LineSegmentOnSegmentEnum.InsideSegment) { overlappedSegment = new LineSegment3D(lineSegment2.startPoint, lineSegment1.endPoint); } if (p2l1_s == LineSegmentOnSegmentEnum.InsideSegment && p2l2_s == LineSegmentOnSegmentEnum.InsideSegment) { overlappedSegment = new LineSegment3D(lineSegment2.endPoint, lineSegment1.endPoint); } mode = LineSegmentOverlapEnum.PartiallyOverlap; } return(true); } else { // if both p1l1 and p2l1 are false, there is probability that the l1 are inside the l2 instead. Only this case needs to be checked since other // cases should be covered by the previous conditional checks bool p1l2 = isInSegment(lineSegment2, lineSegment1.startPoint, out p1l2_s); bool p2l2 = isInSegment(lineSegment2, lineSegment1.endPoint, out p2l2_s); if ((p1l2 && p2l2) && (p1l2_s == p2l2_s && p1l2_s == LineSegmentOnSegmentEnum.InsideSegment)) { mode = LineSegmentOverlapEnum.SuperSegment; overlappedSegment = lineSegment1; return(true); } } return(false); }
/// <summary> /// Calculating intersection beween 2 Faces. The outcome of the intersection should be a LineSegment /// </summary> /// <param name="F1">First Face</param> /// <param name="F2">Second Face</param> /// <param name="intersectionLine">The resulting intersection line. Zero if no intersection</param> /// <param name="mode">The mode of the intersection: No intersection/parallel, partially intersect, no actual intersection/undefined</param> /// <returns></returns> public static bool intersect(Face3D F1, Face3D F2, out LineSegment3D intersectionLine, out FaceIntersectEnum mode) { intersectionLine = new LineSegment3D(new Point3D(0, 0, 0), new Point3D(0, 0, 0)); mode = FaceIntersectEnum.Undefined; if (F1._basePlane.normalVector == F2._basePlane.normalVector) { // test points inside another face for (int i = 0; i < F2._vertices.Count; i++) { if (!Face3D.inside(F1, F2._vertices[i])) { continue; } mode = FaceIntersectEnum.Overlap; return(true); } mode = FaceIntersectEnum.NoIntersectionParallel; return(false); } LineSegment3D ls1; LineSegment3D ls2; bool res1 = Plane3D.PPintersect(F1._basePlane, F2, out ls1); bool res2 = Plane3D.PPintersect(F2._basePlane, F1, out ls2); if (!res1 || !res2) { return(false); // the faces do not intersect } // Special case if the intersection occurs only at a single point if (ls1.startPoint == ls1.endPoint && ls2.startPoint == ls2.endPoint) { if (ls1.startPoint.Equals(ls2.startPoint)) { mode = FaceIntersectEnum.IntersectPartial; return(true); } return(false); } else if (ls1.startPoint.Equals(ls1.endPoint)) { // a single point intersection: ls1 is 0 length linesegnment = point if (LineSegment3D.isInSegment(ls2, ls1.startPoint)) { mode = FaceIntersectEnum.IntersectPartial; return(true); } return(false); } else if (ls2.startPoint.Equals(ls2.endPoint)) { // a single point intersection: ls1 is 0 length linesegnment = point if (LineSegment3D.isInSegment(ls1, ls2.startPoint)) { mode = FaceIntersectEnum.IntersectPartial; return(true); } return(false); } LineSegment3D ovSegment; LineSegmentOverlapEnum ovstat = LineSegmentOverlapEnum.Undefined; bool lint = LineSegment3D.overlap(ls1, ls2, out ovSegment, out ovstat); if (lint) { intersectionLine = ovSegment; mode = FaceIntersectEnum.IntersectPartial; return(true); } return(false); }