public static Point GetInsidePoint(IReadOnlyList <Point> points, Box boundingBox)
        {
            var y = (boundingBox.MinY + boundingBox.MaxY) / 2;
            var xIntersections = new List <double>();
            var point1         = points.Last();

            foreach (var point2 in points)
            {
                if ((y > point1.Y) != (y > point2.Y))
                {
                    xIntersections.Add((y - point2.Y) * (point1.X - point2.X) / (point1.Y - point2.Y) + point2.X);
                }
                point1 = point2;
            }
            xIntersections.Sort();
            Debugger.BreakWhen(xIntersections.Count == 0 || xIntersections.Count % 2 != 0);
            var x        = (boundingBox.MinX + boundingBox.MaxX) / 2;
            var maxDelta = double.NegativeInfinity;

            for (var i = 0; i < xIntersections.Count - 1; i += 2)
            {
                var delta = Math.Abs(xIntersections[i] - xIntersections[i + 1]);
                if (delta > maxDelta)
                {
                    x        = (xIntersections[i] + xIntersections[i + 1]) / 2;
                    maxDelta = delta;
                }
            }
            var point = new Point(x, y);

#if DEBUG
            Debugger.BreakWhen(!PointInPolygonTest.Contains(points, point));
#endif
            return(point);
        }
Exemple #2
0
        public static IEnumerable <Subpath> Unify(IEnumerable <Subpath> subpaths)
        {
            var collection = new SubpathCollection();

            foreach (var subpath in subpaths)
            {
                if (subpath.AreSegmentsClosed)
                {
                    if (HasFillArea(subpath))
                    {
                        yield return(subpath);
                    }
                }
                else
                {
                    collection.Add(subpath);
                }
            }
            var subpath1 = collection.Dequeue();

            while (subpath1 != null)
            {
                var concatenations = collection.GetAll(subpath1.EndPoint).ToArray();
                Debugger.BreakWhen(concatenations.Length == 0);
                if (concatenations.Length > 0)
                {
                    var subpath2 = ChooseConcatenation(subpath1, concatenations);
                    collection.Remove(subpath2);
                    subpath1 = new Subpath(subpath1.StartPoint, subpath1.Segments.Concat(subpath2.Segments), false);
                    if (!subpath1.AreSegmentsClosed)
                    {
                        continue;
                    }
                }
                if (HasFillArea(subpath1))
                {
                    yield return(subpath1);
                }
                subpath1 = collection.Dequeue();
            }
        }
Exemple #3
0
        private static Point SplitByNextIntersection(Point startPoint, SegmentBase segment, out SegmentBase segment1, out SegmentBase segment2,
                                                     CurveEquation equation,
                                                     Func <double, Point, SegmentBase> factory1,
                                                     Func <double, SegmentBase> factory2)
        {
            var intersection = segment.Intersections.Select(x => new { Point = x, T = equation.GetT(x) }).MinBy(x => x.T);
            var t            = Math.Min(Math.Max(intersection.T, 0), 1);
            var point        = equation.GetPoint(t);

            segment1 = point == startPoint ? null : factory1(t, intersection.Point);
            if (point == segment.EndPoint)
            {
                segment2 = null;
                Debugger.BreakWhen(segment.Intersections.Count > 1);
            }
            else
            {
                segment2 = factory2(t);
                segment2.Intersections.AddRange(segment.Intersections.Where(x => x != intersection.Point));
            }
            return(intersection.Point);
        }