예제 #1
0
        /// <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);
        }