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); }
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(); } }
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); }