public static Point SplitByNextIntersection(Point startPoint, LineSegment segment, out SegmentBase segment1, out SegmentBase segment2)
 {
     return SplitByNextIntersection(startPoint, segment, out segment1, out segment2,
         new LineEquation(startPoint, segment),
         (t, p) => new LineSegment(p),
         t => new LineSegment(segment.EndPoint));
 }
 public static Point SplitByNextIntersection(Point startPoint, QuadraticBezierSegment segment, out SegmentBase segment1, out SegmentBase segment2)
 {
     return SplitByNextIntersection(startPoint, segment, out segment1, out segment2,
         new QuadraticBezierEquation(startPoint, segment),
         (t, p) => new QuadraticBezierSegment(Mid(startPoint, segment.ControlPoint, t), p),
         t => new QuadraticBezierSegment(Mid(segment.ControlPoint, segment.EndPoint, t), segment.EndPoint));
 }
 public static Point SplitByNextIntersection(Point startPoint, EllipticalArcSegment segment, out SegmentBase segment1, out SegmentBase segment2)
 {
     Func<Point, EllipticalArcSegment> create = p => new EllipticalArcSegment(segment.Radii, segment.XAxisRotation, segment.IsLargeArc, segment.IsSweep, p);
     return SplitByNextIntersection(startPoint, segment, out segment1, out segment2,
         new EllipticalArcEquation(startPoint, segment),
         (t, p) => create(p),
         t => create(segment.EndPoint));
 }
 private static bool IsDegenerate(Point startPoint, SegmentBase segment)
 {
     if (segment is LineSegment || segment is EllipticalArcSegment)
     {
         return segment.EndPoint == startPoint;
     }
     return false;
 }
 public static Subpath ReverseDirection(Subpath subpath)
 {
     var segments = new SegmentBase[subpath.Segments.Count];
     var startPoint = subpath.StartPoint;
     for (var i = 0; i < segments.Length; i++)
     {
         var segment = subpath.Segments[i];
         segments[i] = segment.Reverse(startPoint);
         startPoint = segment.EndPoint;
     }
     Array.Reverse(segments);
     return new Subpath(startPoint, segments, subpath.IsClosed);
 }
 public static Point SplitByNextIntersection(Point startPoint, CubicBezierSegment segment, out SegmentBase segment1, out SegmentBase segment2)
 {
     return SplitByNextIntersection(startPoint, segment, out segment1, out segment2,
         new CubicBezierEquation(startPoint, segment),
         (t, p) =>
         {
             var a = Mid(startPoint, segment.ControlPoint1, t);
             var b = Mid(segment.ControlPoint1, segment.ControlPoint2, t);
             return new CubicBezierSegment(a, Mid(a, b, t), p);
         },
         t =>
         {
             var b = Mid(segment.ControlPoint1, segment.ControlPoint2, t);
             var c = Mid(segment.ControlPoint2, segment.EndPoint, t);
             return new CubicBezierSegment(Mid(b, c, t), c, segment.EndPoint);
         });
 }
 private static void CalculateIntersections(SegmentBase segment1, SegmentBase segment2, bool skipInner, bool skipOuter)
 {
     var boundingBox1 = segment1.PolylineApproximation.BoundingBox;
     var boundingBox2 = segment2.PolylineApproximation.BoundingBox;
     if (!boundingBox1.IntersectsWith(boundingBox2))
     {
         return;
     }
     var points1 = segment1.PolylineApproximation.Points;
     var points2 = segment2.PolylineApproximation.Points;
     for (var i = 1; i < points1.Count; i++)
     {
         var p11 = points1[i - 1];
         var p12 = points1[i];
         var box1 = new Box(p11, p12);
         if (!box1.IntersectsWith(boundingBox2))
         {
             continue;
         }
         for (var j = 1; j < points2.Count; j++)
         {
             var p21 = points2[j - 1];
             var p22 = points2[j];
             var box2 = new Box(p21, p22);
             if (!box1.IntersectsWith(box2))
             {
                 continue;
             }
             if ((skipInner && i == points1.Count - 1 && j == 1) ||
                 (skipOuter && i == 1 && j == points2.Count - 1))
             {
                 continue;
             }
             var intersection = CalculateIntersection(p11, p12, p21, p22);
             if (intersection.HasValue)
             {
                 segment1.Intersections.Add(intersection.Value);
                 segment2.Intersections.Add(intersection.Value);
             }
         }
     }
 }
 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;
 }
 private static SegmentBase Simplify(Point startPoint, SegmentBase segment)
 {
     var endPoint = segment.EndPoint;
     var simplifyToLine = false;
     if (segment is EllipticalArcSegment)
     {
         var x = (EllipticalArcSegment)segment;
         simplifyToLine = x.Radii.X.IsZero() || x.Radii.Y.IsZero();
     }
     if (segment is QuadraticBezierSegment)
     {
         var x = (QuadraticBezierSegment)segment;
         simplifyToLine = x.ControlPoint == startPoint || x.ControlPoint == endPoint;
     }
     if (segment is CubicBezierSegment)
     {
         var x = (CubicBezierSegment)segment;
         simplifyToLine = (x.ControlPoint1 == startPoint || x.ControlPoint1 == endPoint) &&
             (x.ControlPoint2 == startPoint || x.ControlPoint2 == endPoint);
     }
     return simplifyToLine ? new LineSegment(endPoint) : segment;
 }
 public override Point SplitByNextIntersection(Point startPoint, out SegmentBase segment1, out SegmentBase segment2)
 {
     return SegmentSplitter.SplitByNextIntersection(startPoint, this, out segment1, out segment2);
 }
예제 #11
0
 public override Point SplitByNextIntersection(Point startPoint, out SegmentBase segment1, out SegmentBase segment2)
 {
     return(SegmentSplitter.SplitByNextIntersection(startPoint, this, out segment1, out segment2));
 }
 private static void CalculateSelfIntersections(SegmentBase segment)
 {
     if (!(segment is CubicBezierSegment))
     {
         // only cubic bezier segment can self-intersect
         return;
     }
     var points = segment.PolylineApproximation.Points;
     for (var i = 1; i < points.Count - 2; i++)
     {
         var p11 = points[i - 1];
         var p12 = points[i];
         var box1 = new Box(p11, p12);
         for (var j = i + 2; j < points.Count; j++)
         {
             var p21 = points[j - 1];
             var p22 = points[j];
             var box2 = new Box(p21, p22);
             if (!box1.IntersectsWith(box2))
             {
                 continue;
             }
             var intersection = CalculateIntersection(p11, p12, p21, p22);
             if (intersection.HasValue)
             {
                 segment.Intersections.Add(intersection.Value);
             }
         }
     }
 }
예제 #13
0
 public abstract Point SplitByNextIntersection(Point startPoint, out SegmentBase segment1, out SegmentBase segment2);
 public abstract Point SplitByNextIntersection(Point startPoint, out SegmentBase segment1, out SegmentBase segment2);