private static Point3D[] GetIntersection_Hull_Plane(ITriangleIndexed[] hull, ITriangle plane) { // Shoot through all the triangles in the hull, and get line segment intersections List<Tuple<Point3D, Point3D>> lineSegments = null; if (hull.Length > 100) { lineSegments = hull. AsParallel(). Select(o => GetIntersection_Plane_Triangle(plane, o)). Where(o => o != null). ToList(); } else { lineSegments = hull. Select(o => GetIntersection_Plane_Triangle(plane, o)). Where(o => o != null). ToList(); } if (lineSegments.Count < 2) { // length of 0 is a clear miss, 1 is just touching //NOTE: All the points could be colinear, and just touching the hull, but deeper analysis is needed return null; } // Stitch the line segments together Point3D[] retVal = GetIntersection_Hull_PlaneSprtStitchSegments(lineSegments); if (retVal == null) { // In some cases, the above method fails, so call the more generic 2D convex hull method //NOTE: This assumes the hull is convex retVal = GetIntersection_Hull_PlaneSprtConvexHull(lineSegments); } // Exit Function return retVal; // could still be null }
private static Point3D[] GetConnectingLines(ITriangleIndexed[] hull, Tuple<int, Point3D> intersect1, Tuple<int, Point3D> intersect2, Point3D outsideCenterPoint) { if (intersect1.Item1 == intersect2.Item1) { // They are intersecting the same triangle. Just return a line between them return new Point3D[] { intersect1.Item2, intersect2.Item2 }; } // Get a line from intersect1 to the edge of its triangle var edgeIntersect1 = GetPointOnTriangleEdge(hull[intersect1.Item1], intersect1.Item2, outsideCenterPoint); // Get a line from intersect2 to the edge of its triangle var edgeIntersect2 = GetPointOnTriangleEdge(hull[intersect2.Item1], intersect2.Item2, outsideCenterPoint); if (edgeIntersect1 == null && edgeIntersect2 == null) { // This should never happen. The only thing I can think of is intersect1 and 2 are intersecting 2 triangles, but right on their edge return new Point3D[] { intersect1.Item2, intersect2.Item2 }; } else if (edgeIntersect1 != null && edgeIntersect2 == null) { return new Point3D[] { intersect1.Item2, edgeIntersect1.Item2, intersect2.Item2 }; } else if (edgeIntersect1 == null && edgeIntersect2 != null) { return new Point3D[] { intersect1.Item2, edgeIntersect2.Item2, intersect2.Item2 }; } // edgeIntersect1 and 2 are both nonnull at this point if (Math3D.IsNearValue(edgeIntersect1.Item2, edgeIntersect2.Item2)) { // intersect1 and 2 are intersecting neighboring triangles, so edgeIntersect1 and 2 are the same point return new Point3D[] { intersect1.Item2, edgeIntersect1.Item2, intersect2.Item2 }; } // If execution gets here, there are triangles between the two intersected triangles passed in // Convert the hull into linked triangles TriangleIndexedLinked[] hullLinked = hull.Select(o => new TriangleIndexedLinked(o.Index0, o.Index1, o.Index2, o.AllPoints)).ToArray(); TriangleIndexedLinked.LinkTriangles_Edges(hullLinked.ToList(), true); return GetConnectingLinesSprtBetween(hullLinked, intersect1, intersect2, edgeIntersect1, edgeIntersect2); }