/// <summary> /// Split this region into two (or more) sub-regions along a straight line /// </summary> /// <param name="splitPt">A point on the splitting line</param> /// <param name="splitDir">The direction of the line</param> /// <param name="splitWidth">Optional. The width of the split.</param> /// <returns>The resultant list of regions. If the line does not bisect /// this region and the region could not be split, this collection will contain /// only the original region.</returns> public IList <PlanarRegion> SplitByLineXY(Vector splitPt, Vector splitDir, double splitWidth = 0) { var result = new List <PlanarRegion>(); var outerInts = Intersect.CurveLineXY(Perimeter, splitPt, splitDir).ToList(); outerInts.Sort(); //TODO: void intersections // Commented out as not finished: /*foreach (var voidCrv in Voids) * { * IList<double> voidInts = Intersect.CurveLineXY(voidCrv, splitPt, splitDir); * }*/ if (outerInts.Count > 1) { for (int i = 0; i < outerInts.Count; i++) { double t0 = outerInts[i]; double t1 = outerInts.GetWrapped(i + 1); Curve newPerimeter = Perimeter.Extract(new Interval(t0, t1))?.ToPolyCurve(); //TODO: Cut through and include voids if (!newPerimeter.Closed) { ((PolyCurve)newPerimeter).Close(); if (splitWidth > 0) { var offsets = new double[newPerimeter.SegmentCount]; offsets[offsets.Length - 1] = splitWidth / 2; var newNewPerimeter = newPerimeter.OffsetInwards(offsets); // Check offset has not inverted perimeter: // TODO: Do this automatically when offsetting? if (newNewPerimeter != null && newNewPerimeter.IsClockwiseXY() == newPerimeter.IsClockwiseXY()) { newPerimeter = newNewPerimeter; } else { newPerimeter = null; } } } if (newPerimeter != null) { result.Add(new PlanarRegion(newPerimeter, Attributes?.Duplicate())); } } } else { result.Add(this); //Return the original } return(result); }