Example #1
0
        /// <summary>
        /// Split a bezier curve into 2 bezier curves, at tau.
        /// </summary>
        /// <param name="bezierCurve">The original bezier curve.</param>
        /// <param name="tau">The t value were to split the curve, usually between 0 and 1, but not necessary.</param>
        public static (PdfPath.BezierCurve, PdfPath.BezierCurve) Split(this PdfPath.BezierCurve bezierCurve, double tau)
        {
            // De Casteljau Algorithm
            PdfPoint[][] points = new PdfPoint[4][];

            points[0] = new[]
            {
                bezierCurve.StartPoint,
                bezierCurve.FirstControlPoint,
                bezierCurve.SecondControlPoint,
                bezierCurve.EndPoint
            };

            points[1] = new PdfPoint[3];
            points[2] = new PdfPoint[2];
            points[3] = new PdfPoint[1];

            for (int j = 1; j <= 3; j++)
            {
                for (int i = 0; i <= 3 - j; i++)
                {
                    var x = (1 - tau) * points[j - 1][i].X + tau * points[j - 1][i + 1].X;
                    var y = (1 - tau) * points[j - 1][i].Y + tau * points[j - 1][i + 1].Y;
                    points[j][i] = new PdfPoint(x, y);
                }
            }

            return(new PdfPath.BezierCurve(points[0][0], points[1][0], points[2][0], points[3][0]),
                   new PdfPath.BezierCurve(points[3][0], points[2][1], points[1][2], points[0][3]));
        }
Example #2
0
        private static PdfPoint[] Intersect(PdfPath.BezierCurve bezierCurve, PdfPoint p1, PdfPoint p2)
        {
            var ts = IntersectT(bezierCurve, p1, p2);

            if (ts == null || ts.Length == 0)
            {
                return(EmptyArray <PdfPoint> .Instance);
            }

            List <PdfPoint> points = new List <PdfPoint>();

            foreach (var t in ts)
            {
                PdfPoint point = new PdfPoint(
                    PdfPath.BezierCurve.ValueWithT(bezierCurve.StartPoint.X,
                                                   bezierCurve.FirstControlPoint.X,
                                                   bezierCurve.SecondControlPoint.X,
                                                   bezierCurve.EndPoint.X,
                                                   t),
                    PdfPath.BezierCurve.ValueWithT(bezierCurve.StartPoint.Y,
                                                   bezierCurve.FirstControlPoint.Y,
                                                   bezierCurve.SecondControlPoint.Y,
                                                   bezierCurve.EndPoint.Y,
                                                   t));
                if (Contains(p1, p2, point))
                {
                    points.Add(point);
                }
            }
            return(points.ToArray());
        }
Example #3
0
        /// <summary>
        /// Get the t values that are the intersections of the line and the curve.
        /// </summary>
        /// <returns>List of t values where the <see cref="PdfPath.BezierCurve"/> and the <see cref="PdfPath.Line"/> intersect.</returns>
        public static double[] FindIntersectionT(this PdfPath.BezierCurve bezierCurve, PdfPath.Line line)
        {
            // if the bounding boxes do not intersect, they cannot intersect
            var bezierBbox = bezierCurve.GetBoundingRectangle();

            if (!bezierBbox.HasValue)
            {
                return(null);
            }
            var lineBbox = line.GetBoundingRectangle();

            if (!lineBbox.HasValue)
            {
                return(null);
            }

            if (!bezierBbox.Value.IntersectsWith(lineBbox.Value))
            {
                return(null);
            }

            double x1 = line.From.X;
            double y1 = line.From.Y;
            double x2 = line.To.X;
            double y2 = line.To.Y;

            return(FindIntersectionT(bezierCurve, x1, y1, x2, y2));
        }
Example #4
0
        /// <summary>
        /// Get the <see cref="PdfPoint"/>s that are the intersections of the line and the curve.
        /// </summary>
        /// <returns></returns>
        public static PdfPoint[] Intersect(this PdfPath.BezierCurve bezierCurve, PdfPath.Line line)
        {
            var ts = FindIntersectionT(bezierCurve, line);

            if (ts.Count() == 0)
            {
                return(null);
            }

            List <PdfPoint> points = new List <PdfPoint>();

            foreach (var t in ts)
            {
                PdfPoint point = new PdfPoint(
                    PdfPath.BezierCurve.ValueWithT(bezierCurve.StartPoint.X,
                                                   bezierCurve.FirstControlPoint.X,
                                                   bezierCurve.SecondControlPoint.X,
                                                   bezierCurve.EndPoint.X,
                                                   t),
                    PdfPath.BezierCurve.ValueWithT(bezierCurve.StartPoint.Y,
                                                   bezierCurve.FirstControlPoint.Y,
                                                   bezierCurve.SecondControlPoint.Y,
                                                   bezierCurve.EndPoint.Y,
                                                   t)
                    );
                points.Add(point);
            }
            return(points.ToArray());
        }
Example #5
0
        private static double[] FindIntersectionT(PdfPath.BezierCurve bezierCurve, double x1, double y1, double x2, double y2)
        {
            double A = (y2 - y1);
            double B = (x1 - x2);
            double C = x1 * (y1 - y2) + y1 * (x2 - x1);

            double alpha = bezierCurve.StartPoint.X * A + bezierCurve.StartPoint.Y * B;
            double beta  = 3.0 * (bezierCurve.FirstControlPoint.X * A + bezierCurve.FirstControlPoint.Y * B);
            double gamma = 3.0 * (bezierCurve.SecondControlPoint.X * A + bezierCurve.SecondControlPoint.Y * B);
            double delta = bezierCurve.EndPoint.X * A + bezierCurve.EndPoint.Y * B;

            double a = (-alpha + beta - gamma + delta);
            double b = (3 * alpha - 2 * beta + gamma);
            double c = -3 * alpha + beta;
            double d = alpha + C;

            var solution = SolveCubicEquation(a, b, c, d);

            return(solution.Where(s => !double.IsNaN(s)).Where(s => s >= -double.Epsilon && s <= 1.0).OrderBy(s => s).ToArray());
        }
Example #6
0
        private static double[] IntersectT(PdfPath.BezierCurve bezierCurve, PdfPoint p1, PdfPoint p2)
        {
            // if the bounding boxes do not intersect, they cannot intersect
            var bezierBbox = bezierCurve.GetBoundingRectangle();

            if (!bezierBbox.HasValue)
            {
                return(null);
            }

            if (bezierBbox.Value.Left > Math.Max(p1.X, p2.X) || Math.Min(p1.X, p2.X) > bezierBbox.Value.Right)
            {
                return(null);
            }

            if (bezierBbox.Value.Top < Math.Min(p1.Y, p2.Y) || Math.Max(p1.Y, p2.Y) < bezierBbox.Value.Bottom)
            {
                return(null);
            }

            double A = (p2.Y - p1.Y);
            double B = (p1.X - p2.X);
            double C = p1.X * (p1.Y - p2.Y) + p1.Y * (p2.X - p1.X);

            double alpha = bezierCurve.StartPoint.X * A + bezierCurve.StartPoint.Y * B;
            double beta  = 3.0 * (bezierCurve.FirstControlPoint.X * A + bezierCurve.FirstControlPoint.Y * B);
            double gamma = 3.0 * (bezierCurve.SecondControlPoint.X * A + bezierCurve.SecondControlPoint.Y * B);
            double delta = bezierCurve.EndPoint.X * A + bezierCurve.EndPoint.Y * B;

            double a = -alpha + beta - gamma + delta;
            double b = 3 * alpha - 2 * beta + gamma;
            double c = -3 * alpha + beta;
            double d = alpha + C;

            var solution = SolveCubicEquation(a, b, c, d);

            return(solution.Where(s => !double.IsNaN(s)).Where(s => s >= -epsilon && (s - 1) <= epsilon).OrderBy(s => s).ToArray());
        }
Example #7
0
 /// <summary>
 /// Get the t values that are the intersections of the line and the curve.
 /// </summary>
 /// <returns>List of t values where the <see cref="PdfPath.BezierCurve"/> and the <see cref="PdfPath.Line"/> intersect.</returns>
 public static double[] IntersectT(this PdfPath.BezierCurve bezierCurve, PdfPath.Line line)
 {
     return(IntersectT(bezierCurve, line.From, line.To));
 }
Example #8
0
 /// <summary>
 /// Get the t values that are the intersections of the line and the curve.
 /// </summary>
 /// <returns>List of t values where the <see cref="PdfPath.BezierCurve"/> and the <see cref="PdfLine"/> intersect.</returns>
 public static double[] IntersectT(this PdfPath.BezierCurve bezierCurve, PdfLine line)
 {
     return(IntersectT(bezierCurve, line.Point1, line.Point2));
 }
Example #9
0
 /// <summary>
 /// Get the <see cref="PdfPoint"/>s that are the intersections of the line and the curve.
 /// </summary>
 public static PdfPoint[] Intersect(this PdfPath.BezierCurve bezierCurve, PdfPath.Line line)
 {
     return(Intersect(bezierCurve, line.From, line.To));
 }
Example #10
0
 private static bool IntersectsWith(PdfPath.BezierCurve bezierCurve, PdfPoint p1, PdfPoint p2)
 {
     return(Intersect(bezierCurve, p1, p2).Length > 0);
 }
Example #11
0
 /// <summary>
 /// Checks if the curve and the line are intersecting.
 /// <para>Avoid using this method as it is not optimised. Use <see cref="Intersect(PdfPath.BezierCurve, PdfPath.Line)"/> instead.</para>
 /// </summary>
 public static bool IntersectsWith(this PdfPath.BezierCurve bezierCurve, PdfPath.Line line)
 {
     return(IntersectsWith(bezierCurve, line.From, line.To));
 }
Example #12
0
 /// <summary>
 /// Checks if the curve and the line are intersecting.
 /// <para>Avoid using this method as it is not optimised. Use <see cref="Intersect(PdfPath.BezierCurve, PdfLine)"/> instead.</para>
 /// </summary>
 public static bool IntersectsWith(this PdfPath.BezierCurve bezierCurve, PdfLine line)
 {
     return(IntersectsWith(bezierCurve, line.Point1, line.Point2));
 }