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