public static List <GeneralPolygon2d> PolygonBoolean( ICollection <GeneralPolygon2d> poly1, ICollection <GeneralPolygon2d> poly2, BooleanOp opType, double minArea = -1) { // handle cases where one list is empty if (poly1.Count == 0) { if (opType == BooleanOp.Difference || opType == BooleanOp.Intersection) { return(new List <GeneralPolygon2d>()); } else { return(DeepCopy.List(poly2)); } } else if (poly2.Count == 0) { if (opType == BooleanOp.Intersection) { return(new List <GeneralPolygon2d>()); } else { return(DeepCopy.List(poly1)); } } double nIntScale = Math.Max(GetIntScale(poly1), GetIntScale(poly2)); if (minArea < 0) { minArea = DiscardMinArea; } try { Clipper clipper = new Clipper(Clipper.ioStrictlySimple); foreach (GeneralPolygon2d sub in poly1) { CPolygonList cpoly = ConvertToClipper(sub, nIntScale); clipper.AddPaths(cpoly, PolyType.ptSubject, true); } foreach (GeneralPolygon2d clip in poly2) { CPolygonList cpoly = ConvertToClipper(clip, nIntScale); clipper.AddPaths(cpoly, PolyType.ptClip, true); } ClipType cType = ClipType.ctUnion; if (opType == BooleanOp.Difference) { cType = ClipType.ctDifference; } else if (opType == BooleanOp.Intersection) { cType = ClipType.ctIntersection; } else if (opType == BooleanOp.Xor) { cType = ClipType.ctXor; } PolyTree tree = new PolyTree(); bool bOK = clipper.Execute(cType, tree); if (bOK == false) { //System.Diagnostics.Debug.WriteLine("ClipperUtil.PolygonBoolean: Clipper failed"); return(new List <GeneralPolygon2d>()); } List <GeneralPolygon2d> result = new List <GeneralPolygon2d>(); for (int ci = 0; ci < tree.ChildCount; ++ci) { Convert(tree.Childs[ci], result, nIntScale, minArea); } return(result); } catch /*(Exception e)*/ { //System.Diagnostics.Debug.WriteLine("ClipperUtil.PolygonBoolean: Clipper threw exception: " + e.Message); return(new List <GeneralPolygon2d>()); } }