예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
 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);
예제 #4
0
 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]);
        }