public static List<Polygon> RemoveOverlap(Polygon polygon1, List<Polygon> polygons) { foreach (var polygon in polygons) { if (!polygon1.IsCoplanarTo(polygon)) { return null; } } var normal = polygon1.NormalDirection; //For clipper, everything must be converted to 2d, so any references to rotation are dealing with that var rotation = GetRotation(normal); var rotated1 = polygon1.Vertices.Shift(rotation); var rotatedPolygons = new List<List<Point>>(); foreach (var polygon in polygons) { rotatedPolygons.Add(polygon.Vertices.Shift(rotation)); } var overlapped = Remove_Overlap_In_XY_Plane(rotated1, rotatedPolygons); if (overlapped.IsNull()) { return null; } for (int i = 0; i < overlapped.Count; i++) { overlapped[i] = RemovePointsTooCloseToEachOther(overlapped[i]); } var depth = rotated1[0].Z; var shiftBack = Shift.ComposeLeftToRight(depth * Direction.Out, rotation.Inverse()); var finalPolygons = new List<Polygon>(); //for some reason, Clipper will sometimes return very thin areas that we consider invalid and overlapping //this function loops over all points in each polygon, and if the angle between any two //segments is greater than 179 degrees, it gets rid of the intermediary point for (int i = 0; i < overlapped.Count; i++) { var pointList = overlapped[i].Shift(shiftBack); for (int j = 0; j < overlapped[i].Count; j++) { var index1 = j; var index2 = j + 1; var index3 = j + 2; if (j == overlapped[i].Count - 1) { index2 = 0; index3 = 1; } if (j == overlapped[i].Count - 2) { index3 = 0; } var seg1 = new LineSegment(pointList[index1], pointList[index2]); var seg2 = new LineSegment(pointList[index2], pointList[index3]); var angleBetween = seg1.AngleBetween(seg2); if (Math.Abs(angleBetween.InDegrees.Value) >= 179) { overlapped[i].RemoveAt(index2); } } } //In rare cases, Clipper will return a polygon with no points, this removes those for (int i = 0; i < overlapped.Count; i++) { if (overlapped[i].Count == 0) { overlapped.RemoveAt(i); } } foreach (var polygonPointList in overlapped) { finalPolygons.Add(new Polygon(polygonPointList.Shift(shiftBack))); } return finalPolygons; }