Пример #1
0
        public static Intersection QuadraticBezierSegmentQuadraticBezierSegmentIntersection00(
            double a1X, double a1Y, double a2X, double a2Y, double a3X, double a3Y,
            double b1X, double b1Y, double b2X, double b2Y, double b3X, double b3Y,
            double epsilon = Epsilon)
        {
            // Initialize the intersection.
            var result = new Intersection(IntersectionStates.NoIntersection);

            // ToDo: Break early if the AABB of the ends and handles do not intersect.
            // ToDo: Break early if the AABB of the curve does not intersect.

            // Parametric matrix form of the Bézier curve
            var xCoeffA = QuadraticBezierBernsteinBasisTests.QuadraticBezierBernsteinBasis(a1X, a2X, a3X);
            var yCoeffA = QuadraticBezierBernsteinBasisTests.QuadraticBezierBernsteinBasis(a1Y, a2Y, a3Y);
            var xCoeffB = QuadraticBezierBernsteinBasisTests.QuadraticBezierBernsteinBasis(b1X, b2X, b3X);
            var yCoeffB = QuadraticBezierBernsteinBasisTests.QuadraticBezierBernsteinBasis(b1Y, b2Y, b3Y);

            IList <double> roots = new List <double>();

            if (yCoeffA.C == 0)
            {
                var v0 = xCoeffA.C * (yCoeffA.A - yCoeffB.A);
                var v1 = v0 - (xCoeffA.B * yCoeffA.B);
                var v2 = v0 + v1;
                var v3 = yCoeffA.B * yCoeffA.B;

                roots = QuarticRootsTests.QuarticRoots(
                    /* t^4 */ xCoeffA.C * yCoeffB.C * yCoeffB.C,
                    /* t^3 */ 2 * xCoeffA.C * yCoeffB.B * yCoeffB.C,
                    /* t^2 */ (xCoeffA.C * yCoeffB.B * yCoeffB.B) - (xCoeffB.C * v3) - (yCoeffB.C * v0) - (yCoeffB.C * v1),
                    /* t^1 */ (-xCoeffB.B * v3) - (yCoeffB.B * v0) - (yCoeffB.B * v1),
                    /* C^0 */ ((xCoeffA.A - xCoeffB.A) * v3) + ((yCoeffA.A - yCoeffB.A) * v1),
                    epsilon);
            }
            else
            {
                var v0 = (xCoeffA.C * yCoeffB.C) - (yCoeffA.C * xCoeffB.C);
                var v1 = (xCoeffA.C * yCoeffB.B) - (xCoeffB.B * yCoeffA.C);
                var v2 = (xCoeffA.B * yCoeffA.C) - (yCoeffA.B * xCoeffA.C);
                var v3 = yCoeffA.A - yCoeffB.A;
                var v4 = (yCoeffA.C * (xCoeffA.A - xCoeffB.A)) - (xCoeffA.C * v3);
                var v5 = (-yCoeffA.B * v2) + (yCoeffA.C * v4);
                var v6 = v2 * v2;
                roots = QuarticRootsTests.QuarticRoots(
                    /* t^4 */ v0 * v0,
                    /* t^3 */ 2 * v0 * v1,
                    /* t^2 */ ((-yCoeffB.C * v6) + (yCoeffA.C * v1 * v1) + (yCoeffA.C * v0 * v4) + (v0 * v5)) / yCoeffA.C,
                    /* t^1 */ ((-yCoeffB.B * v6) + (yCoeffA.C * v1 * v4) + (v1 * v5)) / yCoeffA.C,
                    /* C^0 */ ((v3 * v6) + (v4 * v5)) / yCoeffA.C,
                    epsilon);
            }

            foreach (var s in roots)
            {
                var point = new Point2D(
                    (xCoeffB.C * s * s) + (xCoeffB.B * s) + xCoeffB.A,
                    (yCoeffB.C * s * s) + (yCoeffB.B * s) + yCoeffB.A);
                if (s >= 0 && s <= 1)
                {
                    var xRoots = QuadraticRootsTests.QuadraticRoots(
                        /* t^2 */ -xCoeffA.C,
                        /* t^1 */ -xCoeffA.B,
                        /* C^0 */ -xCoeffA.A + point.X,
                        epsilon);
                    var yRoots = QuadraticRootsTests.QuadraticRoots(
                        /* t^2 */ -yCoeffA.C,
                        /* t^1 */ -yCoeffA.B,
                        /* C^0 */ -yCoeffA.A + point.Y,
                        epsilon);

                    if (xRoots.Count > 0 && yRoots.Count > 0)
                    {
                        // Find the nearest matching x and y roots in the ranges 0 < x < 1; 0 < y < 1.
                        foreach (var xRoot in xRoots)
                        {
                            if (xRoot >= 0 && xRoot <= 1)
                            {
                                foreach (var yRoot in yRoots)
                                {
                                    var t = xRoot - yRoot;
                                    if ((t >= 0 ? t : -t) < epsilon)
                                    {
                                        result.AppendPoint(point);
                                        goto checkRoots; // Break through two levels of foreach loops to exit early. Using goto for performance.
                                    }
                                }
                            }
                        }
                        checkRoots :;
                    }
                }
            }

            if (result.Items.Count > 0)
            {
                result.State = IntersectionStates.Intersection;
            }

            return(result);
        }
 public static Intersection QuadraticBezierSegmentOrthogonalEllipseIntersection(double b1X, double b1Y, double b2X, double b2Y, double b3X, double b3Y, double ecX, double ecY, double rx, double ry, double epsilon = double.Epsilon) => BernsteinQuadraticBezierSegmentOrthogonalEllipseIntersectionTests.QuadraticBezierSegmentOrthogonalEllipseIntersection(QuadraticBezierBernsteinBasisTests.QuadraticBezierBernsteinBasis(b1X, b2X, b3X), QuadraticBezierBernsteinBasisTests.QuadraticBezierBernsteinBasis(b1Y, b2Y, b3Y), ecX, ecY, rx, ry, epsilon);
Пример #3
0
        public static Intersection QuadraticBezierSegmentQuadraticBezierSegmentIntersection0(
            double a1X, double a1Y, double a2X, double a2Y, double a3X, double a3Y,
            double b1X, double b1Y, double b2X, double b2Y, double b3X, double b3Y,
            double epsilon = Epsilon)
        {
            // Initialize the intersection.
            var result = new Intersection(IntersectionStates.NoIntersection);

            var xCoeffA = QuadraticBezierBernsteinBasisTests.QuadraticBezierBernsteinBasis(a1X, a2X, a3X);
            var yCoeffA = QuadraticBezierBernsteinBasisTests.QuadraticBezierBernsteinBasis(a1Y, a2Y, a3Y);
            var xCoeffB = QuadraticBezierBernsteinBasisTests.QuadraticBezierBernsteinBasis(b1X, b2X, b3X);
            var yCoeffB = QuadraticBezierBernsteinBasisTests.QuadraticBezierBernsteinBasis(b1Y, b2Y, b3Y);

            var a = (xCoeffA.C * yCoeffA.B) - (xCoeffA.B * yCoeffA.C);
            var b = (xCoeffB.C * yCoeffA.B) - (xCoeffA.B * yCoeffB.C);

            var c = (xCoeffB.B * yCoeffA.B) - (xCoeffA.B * yCoeffB.B);
            var d = (xCoeffA.B * (yCoeffA.A - yCoeffB.A)) - (yCoeffA.B * (xCoeffB.A - xCoeffA.A));
            var e = (xCoeffB.C * yCoeffA.C) - (xCoeffA.C * yCoeffB.C);
            var f = (xCoeffB.B * yCoeffA.C) - (xCoeffA.C * yCoeffB.B);
            var g = (xCoeffA.C * (yCoeffA.A - yCoeffB.A)) - (yCoeffA.C * (yCoeffB.A - xCoeffA.A));

            var roots = QuarticRootsTests.QuarticRoots(
                /* t^4 */ e * e,
                /* t^3 */ 2 * e * f,
                /* t^2 */ (-a * b) + (f * f) + (2 * e * g),
                /* t^1 */ (-a * c) + (2 * f * g),
                /* C */ (-a * d) + (g * g),
                epsilon);

            foreach (var s in roots)
            {
                var point = new Point2D(
                    (xCoeffB.C * s * s) + (xCoeffB.B * s) + xCoeffB.A,
                    (yCoeffB.C * s * s) + (yCoeffB.B * s) + yCoeffB.A);
                if (s >= 0 && s <= 1)
                {
                    var xRoots = QuadraticRootsTests.QuadraticRoots(
                        /* t^2 */ -xCoeffA.C,
                        /* t^1 */ -xCoeffA.B,
                        /* C */ -xCoeffA.A + point.X,
                        epsilon);
                    var yRoots = QuadraticRootsTests.QuadraticRoots(
                        /* t^2 */ -yCoeffA.C,
                        /* t^1 */ -yCoeffA.B,
                        /* C */ -yCoeffA.A + point.Y,
                        epsilon);

                    if (xRoots.Count > 0 && yRoots.Count > 0)
                    {
                        // Find the nearest matching x and y roots in the ranges 0 < x < 1; 0 < y < 1.
                        foreach (var xRoot in xRoots)
                        {
                            if (xRoot >= 0 && xRoot <= 1)
                            {
                                foreach (var yRoot in yRoots)
                                {
                                    var t = xRoot - yRoot;
                                    if ((t >= 0 ? t : -t) < 0.06) // ToDo: Find the error and replace 0.06 with epsilon.
                                    {
                                        result.AppendPoint(point);
                                        goto checkRoots; // Break through two levels of foreach loops. Using goto for performance.
                                    }
                                }
                            }
                        }
                        checkRoots :;
                    }
                }
            }

            if (result.Items.Count > 0)
            {
                result.State = IntersectionStates.Intersection;
            }

            return(result);
        }