コード例 #1
0
        public static IShapeSegment[] SplitRay1(double x, double y, double i, double j, params double[] ts)
        {
            if (ts is null)
            {
                return(new IShapeSegment[] { new Ray2D(x, y, i, j) });
            }

            var filtered = ts.Where(t => t >= 0).Distinct().OrderBy(t => t).ToArray();

            if (filtered.Length == 0)
            {
                return(new IShapeSegment[] { new Ray2D(x, y, i, j) });
            }

            var n      = filtered.Length;
            var shapes = new IShapeSegment[n + 1];
            var prev   = (x, y);

            for (var index = 0; index < n; index++)
            {
                var next = InterpolateLinear2DTests.LinearInterpolate2D(filtered[index], x, y, x + i, y + j);
                shapes[index] = new LineSegment2D(prev, next);
                prev          = next;
            }

            shapes[^ 1] = new Ray2D(prev, (i, j));
コード例 #2
0
        public static LineSegment2D[] Split1(double aX, double aY, double bX, double bY, params double[] ts)
        {
            if (ts is null)
            {
                return(new[] { new LineSegment2D(aX, aY, bX, bY) });
            }

            var filtered = ts.Where(t => t >= 0d && t <= 1d).Distinct().OrderBy(t => t).ToArray();
            var start    = new LineSegment2D(aX, aY, bX, bY);

            if (filtered.Length == 0)
            {
                return(new[] { start });
            }

            var list     = new LineSegment2D[filtered.Length + 1];
            var previous = start.A;

            for (var i = 0; i < filtered.Length; i++)
            {
                var next = InterpolateLinear2DTests.LinearInterpolate2D(filtered[i], aX, aY, bX, bY);
                list[i]  = new LineSegment2D(previous, next);
                previous = next;
            }

            list[^ 1] = new LineSegment2D(previous, (bX, bY));
コード例 #3
0
        /// <summary>
        /// The offset interpolate.
        /// </summary>
        /// <param name="Value1">The Value1.</param>
        /// <param name="Value2">The Value2.</param>
        /// <param name="Offset">The Offset.</param>
        /// <param name="Weight">The Weight.</param>
        /// <returns>The <see cref="Point2D"/>.</returns>
        public static Point2D OffsetInterpolate(Point2D Value1, Point2D Value2, double Offset, double Weight)
        {
            var UnitVectorAB    = new Vector2D(Value1, Value2);
            var PerpendicularAB = new Vector2D(PerpendicularClockwiseVectorTests.PerpendicularClockwise(UnitVectorAB.I, UnitVectorAB.J)) * 0.5d * Offset;

            return(new Point2D(InterpolateLinear2DTests.LinearInterpolate2D(Weight, Value1.X, Value1.Y, Value2.X, Value2.Y)) * (Size2D)PerpendicularAB);
        }
コード例 #4
0
        public static (double X, double Y) BezierSextic(double t, double aX, double aY, double bX, double bY, double cX, double cY, double dX, double dY, double eX, double eY, double fX, double fY, double gX, double gY)
        {
            var abcdef = InterpolateBezierQuintic2DTests.BezierQuintic(t, aX, aY, bX, bY, cX, cY, dX, dY, eX, eY, fX, fY);
            var bcdefg = InterpolateBezierQuintic2DTests.BezierQuintic(t, bX, bY, cX, cY, dX, dY, eX, eY, fX, fY, gX, gY);

            return(InterpolateLinear2DTests.LinearInterpolate2D(t, abcdef.X, abcdef.Y, bcdefg.X, bcdefg.Y));
        }
コード例 #5
0
        public static (IShapeSegment, IShapeSegment) BisectLineSegment1(double aX, double aY, double bX, double bY, double t)
        {
            if (t <= 0d)
            {
                return (
                    new Point2D(aX, aY),
                    new LineSegment2D(aX, aY, bX, bY)
                );
            }

            if (t >= 1d)
            {
                return (
                    new LineSegment2D(aX, aY, bX, bY),
                    new Point2D(bX, bY)
                );
            }

            var (cX, cY) = InterpolateLinear2DTests.LinearInterpolate2D(t, aX, aY, bX, bY);

            return (
                new LineSegment2D(aX, aY, cX, cY),
                new LineSegment2D(cX, cY, bX, bY)
            );
        }
        public static Point2D QuadraticBezierEnvelope0(
            Point2D point,
            Rectangle2D bounds,
            Point2D topLeft, Point2D topHandle, Point2D topRight, Point2D rightHandle,
            Point2D bottomRight, Point2D bottomHandle, Point2D bottomLeft, Point2D leftHandle)
        {
            // topLeft                             topRight
            //   0------------------0------------------0
            //   |              topHandle              |
            //   |                                     |
            //   |                                     |
            //   |                                     |
            //   |                                     |
            //   0 leftHandle              rightHandle 0
            //   |                                     |
            //   |                                     |
            //   |                                     |
            //   |                                     |
            //   |             bottomHandle            |
            //   0------------------0------------------0
            // bottomLeft                       bottomRight
            //
            // Install "Match Margin" Extension to enable word match highlighting, to help visualize where a variable resides in the ASCI map.

            var normal      = (X : (point.X - bounds.X) / bounds.Width, Y : (point.Y - bounds.Top) / bounds.Height);
            var leftAnchor  = InterpolateBezierQuadratic2DTests.QuadraticBezierInterpolate2D(normal.Y, topLeft.X, topLeft.Y, leftHandle.X, leftHandle.Y, bottomLeft.X, bottomLeft.Y);
            var handle      = InterpolateLinear2DTests.LinearInterpolate2D(normal.Y, topHandle.X, topHandle.Y, bottomHandle.X, bottomHandle.Y);
            var rightAnchor = InterpolateBezierQuadratic2DTests.QuadraticBezierInterpolate2D(normal.Y, topRight.X, topRight.Y, rightHandle.X, rightHandle.Y, bottomRight.X, bottomRight.Y);

            return(new Point2D(InterpolateBezierQuadratic2DTests.QuadraticBezierInterpolate2D(normal.X, leftAnchor.X, leftAnchor.Y, handle.X, handle.Y, rightAnchor.X, rightAnchor.Y)));
        }
コード例 #7
0
        public static Point2D CubicBezierEnvelope0(
            Point2D point,
            Rectangle2D bounds,
            Point2D topLeft, Point2D topLeftH, Point2D topLeftV,
            Point2D topRight, Point2D topRightH, Point2D topRightV,
            Point2D bottomRight, Point2D bottomRightH, Point2D bottomRightV,
            Point2D bottomLeft, Point2D bottomLeftH, Point2D bottomLeftV)
        {
            // topLeft                             topRight
            //   0--------0                 0----------0
            //   |   topLeftH             topRightH    |
            //   |                                     |
            //   |                                     |
            //   0 topLeftV                  topRightV 0
            //
            //
            //
            //   0 bottomLeftV            bottomRightV 0
            //   |                                     |
            //   |                                     |
            //   |  bottomLeftH         bottomRightH   |
            //   0--------0                 0----------0
            // bottomLeft                       bottomRight
            //
            // Install "Match Margin" Extension to enable word match highlighting, to help visualize where a variable resides in the ASCI map.

            var normal      = (X : (point.X - bounds.X) / bounds.Width, Y : (point.Y - bounds.Top) / bounds.Height);
            var leftAnchor  = BezierInterpolateCubic2DTests.CubicBezierCurve(normal.Y, topLeft.X, topLeft.Y, topLeftV.X, topLeftV.Y, bottomLeftV.X, bottomLeftV.Y, bottomLeft.X, bottomLeft.Y);
            var leftHandle  = InterpolateLinear2DTests.LinearInterpolate2D(normal.Y, topLeftH.X, topLeftH.Y, bottomLeftH.X, bottomLeftH.Y);
            var rightHandle = InterpolateLinear2DTests.LinearInterpolate2D(normal.Y, topRightH.X, topRightH.Y, bottomRightH.X, bottomRightH.Y);
            var rightAnchor = BezierInterpolateCubic2DTests.CubicBezierCurve(normal.Y, topRight.X, topRight.Y, topRightV.X, topRightV.Y, bottomRightV.X, bottomRightV.Y, bottomRight.X, bottomRight.Y);

            return(new Point2D(BezierInterpolateCubic2DTests.CubicBezierCurve(normal.X, leftAnchor.X, leftAnchor.Y, leftHandle.X, leftHandle.Y, rightHandle.X, rightHandle.Y, rightAnchor.X, rightAnchor.Y)));
        }
コード例 #8
0
        public static Intersection QuadraticBezierLineSegmentIntersection0(
            double p1X, double p1Y,
            double p2X, double p2Y,
            double p3X, double p3Y,
            double a1X, double a1Y,
            double a2X, double a2Y,
            double epsilon = Epsilon)
        {
            var min    = MinPointTests.MinPoint(a1X, a1Y, a2X, a2Y);
            var max    = MaxPointTests.MaxPoint(a1X, a1Y, a2X, a2Y);
            var result = new Intersection(IntersectionStates.NoIntersection);
            var a      = new Vector2D(p2X, p2Y) * (-2);
            var c2     = new Vector2D(p1X, p1Y) + (a + new Vector2D(p3X, p3Y));

            a = new Vector2D(p1X, p1Y) * (-2);
            var b     = new Vector2D(p2X, p2Y) * 2;
            var c1    = a + b;
            var c0    = new Point2D(p1X, p1Y);
            var n     = new Point2D(a1Y - a2Y, a2X - a1X);
            var cl    = (a1X * a2Y) - (a2X * a1Y);
            var roots = QuadraticRootsTests.QuadraticRoots(
                DotProduct2Vector2DTests.DotProduct2D(n.X, n.Y, c2.I, c2.J),
                DotProduct2Vector2DTests.DotProduct2D(n.X, n.Y, c1.I, c1.J),
                DotProduct2Vector2DTests.DotProduct2D(n.X, n.Y, c0.X + cl, c0.Y + cl),
                epsilon);

            for (var i = 0; i < roots.Count; i++)
            {
                var t = roots[i];
                if (0 <= t && t <= 1)
                {
                    var p4 = InterpolateLinear2DTests.LinearInterpolate2D(t, p1X, p1Y, p2X, p2Y);
                    var p5 = InterpolateLinear2DTests.LinearInterpolate2D(t, p2X, p2Y, p3X, p3Y);
                    var p6 = InterpolateLinear2DTests.LinearInterpolate2D(t, p4.X, p4.Y, p5.X, p5.Y);
                    if (a1X == a2X)
                    {
                        if (min.Y <= p6.Y && p6.Y <= max.Y)
                        {
                            result.State = IntersectionStates.Intersection;
                            result.AppendPoint(p6);
                        }
                    }
                    else if (a1Y == a2Y)
                    {
                        if (min.X <= p6.X && p6.X <= max.X)
                        {
                            result.State = IntersectionStates.Intersection;
                            result.AppendPoint(p6);
                        }
                    }
                    else if (GreaterThanOrEqualTests.GreaterThanOrEqual(p6.X, p6.Y, min.X, min.Y) && LessThanOrEqualTests.LessThanOrEqual(p6.X, p6.Y, max.X, max.Y))
                    {
                        result.State = IntersectionStates.Intersection;
                        result.AppendPoint(p6);
                    }
                }
            }
            return(result);
        }
コード例 #9
0
        public static (double aX, double aY, double bX, double bY, double cX, double cY) LineSegmentToQuadraticBezier0(
            double x0, double y0,
            double x1, double y1)
        {
            var p = InterpolateLinear2DTests.LinearInterpolate2D(OneHalf, x0, y0, x1, y1);

            return(x0, y0, p.X, p.Y, x1, y1);
        }
コード例 #10
0
        public static QuadraticBezier2D LeftBisectQuadraticBezier1(double aX, double aY, double bX, double bY, double cX, double cY, double t)
        {
            var(dX, dY) = InterpolateLinear2DTests.LinearInterpolate2D(t, aX, aY, bX, bY);
            var(eX, eY) = InterpolateLinear2DTests.LinearInterpolate2D(t, bX, bY, cX, cY);
            var(fX, fY) = InterpolateLinear2DTests.LinearInterpolate2D(t, dX, dY, eX, eY);

            return(new QuadraticBezier2D(aX, aY, dX, dY, fX, fY));
        }
コード例 #11
0
        public static (IShapeSegment A, IShapeSegment B) BisectRay1(double x, double y, double i, double j, double t)
        {
            var(X, Y) = InterpolateLinear2DTests.LinearInterpolate2D(t, x, y, x + i, y + j);

            return(
                new LineSegment2D(x, y, X, Y),
                new Ray2D(X, Y, i, j)
                );
        }
コード例 #12
0
        public static (Ray2D RayA, Ray2D RayB) BisectLine1(double x, double y, double i, double j, double t)
        {
            var(hX, hY) = InterpolateLinear2DTests.LinearInterpolate2D(t, x, y, x + i, y + j);

            return(
                new Ray2D(hX, hY, -i, -j),
                new Ray2D(hX, hY, i, j)
                );
        }
コード例 #13
0
        public static (double aX, double aY, double bX, double bY, double cX, double cY, double dX, double dY) LineSegmentToCubicBezier0(
            double x0, double y0,
            double x1, double y1)
        {
            var p2 = InterpolateLinear2DTests.LinearInterpolate2D(OneThird, x0, y0, x1, y1);
            var p3 = InterpolateLinear2DTests.LinearInterpolate2D(TwoThirds, x0, y0, x1, y1);

            return(x0, y0, p2.X, p2.Y, p3.X, p3.Y, x1, y1);
        }
コード例 #14
0
        public static (double X, double Y) QuadraticBezierInterpolate2D1(double t, double x0, double y0, double x1, double y1, double x2, double y2)
        {
            // point between a and b
            var ab = InterpolateLinear2DTests.LinearInterpolate2D(t, x0, y0, x1, y1);

            // point between b and c
            var bc = InterpolateLinear2DTests.LinearInterpolate2D(t, x1, y1, x2, y2);

            // point on the bezier-curve
            return(InterpolateLinear2DTests.LinearInterpolate2D(t, ab.X, ab.Y, bc.X, bc.Y));
        }
コード例 #15
0
        public static CubicBezier2D RightBisectCubicBezier1(double aX, double aY, double bX, double bY, double cX, double cY, double dX, double dY, double t)
        {
            var(eX, eY) = InterpolateLinear2DTests.LinearInterpolate2D(t, aX, aY, bX, bY);
            var(fX, fY) = InterpolateLinear2DTests.LinearInterpolate2D(t, bX, bY, cX, cY);
            var(gX, gY) = InterpolateLinear2DTests.LinearInterpolate2D(t, cX, cY, dX, dY);
            var(hX, hY) = InterpolateLinear2DTests.LinearInterpolate2D(t, eX, eY, fX, fY);
            var(jX, jY) = InterpolateLinear2DTests.LinearInterpolate2D(t, fX, fY, gX, gY);
            var(kX, kY) = InterpolateLinear2DTests.LinearInterpolate2D(t, hX, hY, jX, jY);

            return(kX, kY, jX, jY, gX, gY, dX, dY);
        }
コード例 #16
0
        public static Intersection CircleLineSegmentIntersectionKevLinDev(
            double cX, double cY,
            double r,
            double lAX, double lAY,
            double lBX, double lBY,
            double epsilon = Epsilon)
        {
            _ = epsilon;
            Intersection result;

            var a = ((lBX - lAX) * (lBX - lAX)) + ((lBY - lAY) * (lBY - lAY));
            var b = 2 * (((lBX - lAX) * (lAX - cX)) + ((lBY - lAY) * (lAY - cY)));
            var c = (cX * cX) + (cY * cY) + (lAX * lAX) + (lAY * lAY) - (2 * ((cX * lAX) + (cY * lAY))) - (r * r);

            var determinant = (b * b) - (4 * a * c);

            if (determinant < 0)
            {
                result = new Intersection(IntersectionStates.Outside);
            }
            else if (determinant == 0)
            {
                result = new Intersection(IntersectionStates.Tangent | IntersectionStates.Intersection);
                var u1 = (-b) / (2 * a);
                if (u1 < 0 || u1 > 1)
                {
                    result = (u1 < 0) || (u1 > 1) ? new Intersection(IntersectionStates.Outside) : new Intersection(IntersectionStates.Inside);
                }
                else
                {
                    result = new Intersection(IntersectionStates.Intersection);
                    if (0 <= u1 && u1 <= 1)
                    {
                        result.Items.Add(InterpolateLinear2DTests.LinearInterpolate2D(u1, lAX, lAY, lBX, lBY));
                    }
                }
            }
            else
            {
                var e  = Sqrt(determinant);
                var u1 = (-b + e) / (2 * a);
                var u2 = (-b - e) / (2 * a);
                if ((u1 < 0 || u1 > 1) && (u2 < 0 || u2 > 1))
                {
                    result = (u1 < 0 && u2 < 0) || (u1 > 1 && u2 > 1) ? new Intersection(IntersectionStates.Outside) : new Intersection(IntersectionStates.Inside);
                }
                else
                {
                    result = new Intersection(IntersectionStates.Intersection);
                    if (0 <= u1 && u1 <= 1)
                    {
                        result.Items.Add(InterpolateLinear2DTests.LinearInterpolate2D(u1, lAX, lAY, lBX, lBY));
                    }

                    if (0 <= u2 && u2 <= 1)
                    {
                        result.Items.Add(InterpolateLinear2DTests.LinearInterpolate2D(u2, lAX, lAY, lBX, lBY));
                    }
                }
            }
            return(result);
        }
コード例 #17
0
        public static Intersection UnrotatedEllipseLineSegmentIntersection0(
            double centerX, double centerY,
            double rx, double ry,
            double a1X, double a1Y,
            double a2X, double a2Y,
            double epsilon = Epsilon)
        {
            _ = epsilon;
            var          origin = new Vector2D(a1X, a1Y);
            var          dir    = new Vector2D(a1X, a1Y, a2X, a2Y);
            var          diff   = origin - new Vector2D(centerX, centerY);
            var          mDir   = new Vector2D(dir.I / (rx * rx), dir.J / (ry * ry));
            var          mDiff  = new Vector2D(diff.I / (rx * rx), diff.J / (ry * ry));
            var          a      = DotProduct2Vector2DTests.DotProduct2D(dir.I, dir.J, mDir.I, mDir.J);
            var          b      = DotProduct2Vector2DTests.DotProduct2D(dir.I, dir.J, mDiff.I, mDiff.J);
            var          c      = DotProduct2Vector2DTests.DotProduct2D(diff.I, diff.J, mDiff.I, mDiff.J) - 1d;
            var          d      = (b * b) - (a * c);
            Intersection result;

            if (d < 0)
            {
                result = new Intersection(IntersectionStates.Outside);
            }
            else if (d > 0)
            {
                var root = Sqrt(d);
                var t_a  = (-b - root) / a;
                var t_b  = (-b + root) / a;
                if ((t_a < 0 || 1 < t_a) && (t_b < 0 || 1 < t_b))
                {
                    result = (t_a < 0 && t_b < 0) || (t_a > 1 && t_b > 1) ? new Intersection(IntersectionStates.Outside) : new Intersection(IntersectionStates.Inside);
                }
                else
                {
                    result = new Intersection(IntersectionStates.Intersection);
                    if (0 <= t_a && t_a <= 1)
                    {
                        result.AppendPoint(InterpolateLinear2DTests.LinearInterpolate2D(t_a, a1X, a1Y, a2X, a2Y));
                    }

                    if (0 <= t_b && t_b <= 1)
                    {
                        result.AppendPoint(InterpolateLinear2DTests.LinearInterpolate2D(t_b, a1X, a1Y, a2X, a2Y));
                    }
                }
            }
            else
            {
                var t = -b / a; if (0 <= t && t <= 1)
                {
                    result = new Intersection(IntersectionStates.Intersection);
                    result.AppendPoint(InterpolateLinear2DTests.LinearInterpolate2D(t, a1X, a1Y, a2X, a2Y));
                }
                else
                {
                    result = new Intersection(IntersectionStates.Outside);
                }
            }

            return(result);
        }
コード例 #18
0
        public static Intersection UnrotatedEllipticalArcLineSegmentIntersection0(
            double cx, double cy,
            double rx, double ry,
            double startAngle, double sweepAngle,
            double x0, double y0,
            double x1, double y1, double epsilon = Epsilon)
        {
            _ = epsilon;
            // Initialize the resulting intersection structure.
            var result = new Intersection(IntersectionStates.NoIntersection);

            // Translate the line to put the ellipse centered at the origin.
            var origin = new Vector2D(x0, y0);
            var dir    = new Vector2D(x0, y0, x1, y1);
            var diff   = origin - new Vector2D(cx, cy);
            var mDir   = new Vector2D(dir.I / (rx * rx), dir.J / (ry * ry));
            var mDiff  = new Vector2D(diff.I / (rx * rx), diff.J / (ry * ry));

            // Calculate the quadratic parameters.
            var a = DotProduct2Vector2DTests.DotProduct2D(dir.I, dir.J, mDir.I, mDir.J);
            var b = DotProduct2Vector2DTests.DotProduct2D(dir.I, dir.J, mDiff.I, mDiff.J);
            var c = DotProduct2Vector2DTests.DotProduct2D(diff.I, diff.J, mDiff.I, mDiff.J) - 1d;

            // Calculate the discriminant of the quadratic. The 4 is omitted.
            var discriminant = (b * b) - (a * c);

            // Check whether line segment is outside of the ellipse.
            if (discriminant < 0d)
            {
                return(new Intersection(IntersectionStates.Outside));
            }

            // Find the start and end angles.
            var sa = EllipticalPolarAngleTests.EllipticalPolarAngle(startAngle, rx, ry);
            var ea = EllipticalPolarAngleTests.EllipticalPolarAngle(startAngle + sweepAngle, rx, ry);

            // Get the ellipse rotation transform.
            var cosT = Cos(0d);
            var sinT = Sin(0d);

            // Ellipse equation for an ellipse at origin for the chord end points.
            var u1 = rx * Cos(sa);
            var v1 = -(ry * Sin(sa));
            var u2 = rx * Cos(ea);
            var v2 = -(ry * Sin(ea));

            // Find the points of the chord.
            var sX = cx + ((u1 * cosT) + (v1 * sinT));
            var sY = cy + ((u1 * sinT) - (v1 * cosT));
            var eX = cx + ((u2 * cosT) + (v2 * sinT));
            var eY = cy + ((u2 * sinT) - (v2 * cosT));

            if (discriminant > 0d)
            {
                // Two real possible solutions.
                var root = Sqrt(discriminant);
                var t1   = (-b - root) / a;
                var t2   = (-b + root) / a;
                if ((t1 < 0d || 1d < t1) && (t2 < 0d || 1d < t2))
                {
                    result = (t1 < 0d && t2 < 0d) || (t1 > 1d && t2 > 1d) ? new Intersection(IntersectionStates.Outside) : new Intersection(IntersectionStates.Inside);
                }
                else
                {
                    var p = InterpolateLinear2DTests.LinearInterpolate2D(t1, x0, y0, x1, y1);
                    // Find the determinant of the chord.
                    var determinant = ((sX - p.X) * (eY - p.Y)) - ((eX - p.X) * (sY - p.Y));

                    // Check whether the point is on the side of the chord as the center.
                    if (0d <= t1 && t1 <= 1d && (Sign(determinant) != Sign(sweepAngle)))
                    {
                        result.AppendPoint(p);
                    }

                    p = InterpolateLinear2DTests.LinearInterpolate2D(t2, x0, y0, x1, y1);
                    // Find the determinant of the chord.
                    determinant = ((sX - p.X) * (eY - p.Y)) - ((eX - p.X) * (sY - p.Y));
                    if (0d <= t2 && t2 <= 1 && (Sign(determinant) != Sign(sweepAngle)))
                    {
                        result.AppendPoint(p);
                    }
                }
            }
            else // discriminant == 0.
            {
                // One real possible solution.
                var t = -b / a;
                if (t >= 0d && t <= 1d)
                {
                    var p = InterpolateLinear2DTests.LinearInterpolate2D(t, x0, y0, x1, y1);

                    // Find the determinant of the matrix representing the chord.
                    var determinant = ((sX - p.X) * (eY - p.Y)) - ((eX - p.X) * (sY - p.Y));

                    // Add the point if it is on the sweep side of the chord.
                    if (Sign(determinant) != Sign(sweepAngle))
                    {
                        result.AppendPoint(InterpolateLinear2DTests.LinearInterpolate2D(t, x0, y0, x1, y1));
                    }
                }
                else
                {
                    result = new Intersection(IntersectionStates.Outside);
                }
            }

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

            return(result);
        }
コード例 #19
0
        public static IShapeSegment LeftBisectRay1(double x, double y, double i, double j, double t)
        {
            var(X, Y) = InterpolateLinear2DTests.LinearInterpolate2D(t, x, y, x + i, y + j);

            return(new LineSegment2D(x, y, X, Y));
        }
コード例 #20
0
 public static (double X, double Y) LineSegmentCenter2(double x1, double y1, double x2, double y2)
 {
     return(InterpolateLinear2DTests.LinearInterpolate2D(0.5d, x1, y1, x2, y2));
 }
コード例 #21
0
        public static Intersection CubicBezierLineIntersection0(
            double p1X, double p1Y,
            double p2X, double p2Y,
            double p3X, double p3Y,
            double p4X, double p4Y,
            double a1X, double a1Y,
            double a2X, double a2Y,
            double epsilon = Epsilon)
        {
            Vector2D a, b, c, d;
            Vector2D c3, c2, c1, c0;
            double   cl;
            Vector2D n;
            var      min    = MinPointTests.MinPoint(a1X, a1Y, a2X, a2Y);
            var      max    = MaxPointTests.MaxPoint(a1X, a1Y, a2X, a2Y);
            var      result = new Intersection(IntersectionStates.NoIntersection);

            a  = new Vector2D(p1X, p1Y) * (-1);
            b  = new Vector2D(p2X, p2Y) * 3;
            c  = new Vector2D(p3X, p3Y) * (-3);
            d  = a + (b + (c + new Vector2D(p4X, p4Y)));
            c3 = new Vector2D(d.I, d.J);
            a  = new Vector2D(p1X, p1Y) * 3;
            b  = new Vector2D(p2X, p2Y) * (-6);
            c  = new Vector2D(p3X, p3Y) * 3;
            d  = a + (b + c);
            c2 = new Vector2D(d.I, d.J);
            a  = new Vector2D(p1X, p1Y) * (-3);
            b  = new Vector2D(p2X, p2Y) * 3;
            c  = a + b;
            c1 = new Vector2D(c.I, c.J);
            c0 = new Vector2D(p1X, p1Y);
            n  = new Vector2D(a1Y - a2Y, a2X - a1X);
            cl = (a1X * a2Y) - (a2X * a1Y);
            var roots = CubicRootsTests.CubicRoots(
                DotProduct2Vector2DTests.DotProduct2D(n.I, n.J, c3.I, c3.J),
                DotProduct2Vector2DTests.DotProduct2D(n.I, n.J, c2.I, c2.J),
                DotProduct2Vector2DTests.DotProduct2D(n.I, n.J, c1.I, c1.J),
                DotProduct2Vector2DTests.DotProduct2D(n.I, n.J, c0.I + cl, c0.J + cl),
                epsilon);

            for (var i = 0; i < roots.Count; i++)
            {
                var t = roots[i];
                if (0 <= t && t <= 1)
                {
                    var p5  = InterpolateLinear2DTests.LinearInterpolate2D(t, p1X, p1Y, p2X, p2Y);
                    var p6  = InterpolateLinear2DTests.LinearInterpolate2D(t, p2X, p2Y, p3X, p3Y);
                    var p7  = InterpolateLinear2DTests.LinearInterpolate2D(t, p3X, p3Y, p4X, p4Y);
                    var p8  = InterpolateLinear2DTests.LinearInterpolate2D(t, p5.X, p5.Y, p6.X, p6.Y);
                    var p9  = InterpolateLinear2DTests.LinearInterpolate2D(t, p6.X, p6.Y, p7.X, p7.Y);
                    var p10 = InterpolateLinear2DTests.LinearInterpolate2D(t, p8.X, p8.Y, p9.X, p9.Y);
                    if (a1X == a2X)
                    {
                        result.State = IntersectionStates.Intersection;
                        result.AppendPoint(p10);
                    }
                    else if (a1Y == a2Y)
                    {
                        result.State = IntersectionStates.Intersection;
                        result.AppendPoint(p10);
                    }
                    else if (GreaterThanOrEqualTests.GreaterThanOrEqual(p10.X, p10.Y, min.X, min.Y) && LessThanOrEqualTests.LessThanOrEqual(p10.X, p10.Y, max.X, max.Y))
                    {
                        result.State = IntersectionStates.Intersection;
                        result.AppendPoint(p10);
                    }
                }
            }

            return(result);
        }