public static Intersection CubicBezierLineSegmentIntersection1( double p0x, double p0y, double p1x, double p1y, double p2x, double p2y, double p3x, double p3y, double l0x, double l0y, double l1x, double l1y, double epsilon = Epsilon) { _ = epsilon; // ToDo: Figure out why this can't handle intersection with horizontal lines. var I = new Intersection(IntersectionStates.NoIntersection); var A = l1y - l0y; //A=y2-y1 var B = l0x - l1x; //B=x1-x2 var C = (l0x * (l0y - l1y)) + (l0y * (l1x - l0x)); //C=x1*(y1-y2)+y1*(x2-x1) var xCoeff = CubicBezierBernsteinBasisTests.CubicBezierBernsteinBasis(p0x, p1x, p2x, p3x); var yCoeff = CubicBezierBernsteinBasisTests.CubicBezierBernsteinBasis(p0y, p1y, p2y, p3y); var r = CubicRootsTests.CubicRoots( /* t^3 */ (A * xCoeff.D) + (B * yCoeff.D), /* t^2 */ (A * xCoeff.C) + (B * yCoeff.C), /* t^1 */ (A * xCoeff.B) + (B * yCoeff.B), /* 1 */ (A * xCoeff.A) + (B * yCoeff.A) + C ); /*verify the roots are in bounds of the linear segment*/ for (var i = 0; i < 3; i++) { var t = r[i]; var x = (xCoeff.D * t * t * t) + (xCoeff.C * t * t) + (xCoeff.B * t) + xCoeff.A; var y = (yCoeff.D * t * t * t) + (yCoeff.C * t * t) + (yCoeff.B * t) + yCoeff.A; /*above is intersection point assuming infinitely long line segment, * make sure we are also in bounds of the line*/ double m; m = (l1x - l0x) != 0 ? (x - l0x) / (l1x - l0x) : (y - l0y) / (l1y - l0y); /*in bounds?*/ if (t < 0 || t > 1d || m < 0 || m > 1d) { x = 0; // -100; /*move off screen*/ y = 0; // -100; } else { /*intersection point*/ I.AppendPoint(new Point2D(x, y)); I.State = IntersectionStates.Intersection; } } return(I); }
public static (double X, double Y)? CubicBezierSelfIntersection1(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3) { var(xCurveA, xCurveB, xCurveC, xCurveD) = CubicBezierBernsteinBasisTests.CubicBezierBernsteinBasis(x0, x1, x2, x3); (var a, var b) = (xCurveD == 0d) ? (xCurveC, xCurveB) : (xCurveC / xCurveD, xCurveB / xCurveD); var(yCurveA, yCurveB, yCurveC, yCurveD) = CubicBezierBernsteinBasisTests.CubicBezierBernsteinBasis(y0, y1, y2, y3); (var p, var q) = (yCurveD == 0d) ? (yCurveC, yCurveB) : (yCurveC / yCurveD, yCurveB / yCurveD); if (a == p || q == b) { return(null); } var k = (q - b) / (a - p); var poly = new double[] { (-k * k * k) - (a * k * k) - (b * k), (3 * k * k) + (2 * k * a) + (2 * b), -3 * k, 2 }; var roots = CubicRootsTests.CubicRoots(poly[3], poly[2], poly[1], poly[0]) .OrderByDescending(c => c).ToArray(); if (roots.Length != 3) { return(null); } if (roots[0] >= 0d && roots[0] <= 1d && roots[2] >= 0d && roots[2] <= 1d) { return(InterpolateCubic2DTests.CubicInterpolate2D(roots[0], x0, y0, x1, y1, x2, y2, x3, y3)); } return(null); }
public static Intersection CubicBezierSegmentOrthogonalEllipseIntersection(double b1X, double b1Y, double b2X, double b2Y, double b3X, double b3Y, double b4X, double b4Y, double h, double k, double a, double b, double epsilon = double.Epsilon) => BernsteinCubicBezierSegmentOrthogonalEllipseIntersectionTests.CubicBezierSegmentOrthogonalEllipseIntersection(CubicBezierBernsteinBasisTests.CubicBezierBernsteinBasis(b1X, b2X, b3X, b4X), CubicBezierBernsteinBasisTests.CubicBezierBernsteinBasis(b1Y, b2Y, b3Y, b4Y), h, k, a, b, epsilon);
public static (double X, double Y)? CubicBezierSelfIntersectionX(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3) { return(CubicBezierSelfIntersectionX( CubicBezierBernsteinBasisTests.CubicBezierBernsteinBasis(x0, x1, x2, x3), CubicBezierBernsteinBasisTests.CubicBezierBernsteinBasis(y0, y1, y2, y3))); }
public static (double A, double B, double C, double D, double E) QuarticBezierCoefficientsRecursive(double a, double b, double c, double d, double e) { var polynomial = (Polynomial.OneMinusT * CubicBezierBernsteinBasisTests.CubicBezierBernsteinBasis(a, b, c, d)) + (Polynomial.T * CubicBezierBernsteinBasisTests.CubicBezierBernsteinBasis(b, c, d, e)); return(polynomial[PolynomialTerm.a], polynomial[PolynomialTerm.b], polynomial[PolynomialTerm.c], polynomial[PolynomialTerm.d], polynomial[PolynomialTerm.e]); }