Пример #1
0
        /// <summary>
        /// The closest point of a parallelogram that intersects with a given line
        /// is the closest such point of each of its four line segments.
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override bool GetNearestIntersectionPoint(PointF p1, PointF p2, out PointF result)
        {
            RectangleF bounds = Bounds;
            float      shift  = PenWidth / 2f;

            PointF[] points  = getPoints();
            PointF   pointF  = GoShape.ExpandPointOnEdge(points[0], bounds, shift);
            PointF   pointF2 = GoShape.ExpandPointOnEdge(points[1], bounds, shift);
            PointF   pointF3 = GoShape.ExpandPointOnEdge(points[2], bounds, shift);
            PointF   pointF4 = GoShape.ExpandPointOnEdge(points[3], bounds, shift);
            float    x       = p1.X;
            float    y       = p1.Y;
            float    num     = 1E+21f;
            PointF   pointF5 = default(PointF);

            if (GoStroke.NearestIntersectionOnLine(pointF, pointF2, p1, p2, out PointF result2))
            {
                float num2 = (result2.X - x) * (result2.X - x) + (result2.Y - y) * (result2.Y - y);
                if (num2 < num)
                {
                    num     = num2;
                    pointF5 = result2;
                }
            }
            if (GoStroke.NearestIntersectionOnLine(pointF2, pointF3, p1, p2, out result2))
            {
                float num3 = (result2.X - x) * (result2.X - x) + (result2.Y - y) * (result2.Y - y);
                if (num3 < num)
                {
                    num     = num3;
                    pointF5 = result2;
                }
            }
            if (GoStroke.NearestIntersectionOnLine(pointF3, pointF4, p1, p2, out result2))
            {
                float num4 = (result2.X - x) * (result2.X - x) + (result2.Y - y) * (result2.Y - y);
                if (num4 < num)
                {
                    num     = num4;
                    pointF5 = result2;
                }
            }
            if (GoStroke.NearestIntersectionOnLine(pointF4, pointF, p1, p2, out result2))
            {
                float num5 = (result2.X - x) * (result2.X - x) + (result2.Y - y) * (result2.Y - y);
                if (num5 < num)
                {
                    num     = num5;
                    pointF5 = result2;
                }
            }
            result = pointF5;
            return(num < 1E+21f);
        }
Пример #2
0
        /// <summary>
        /// The closest intersection point of a polygon with a line is the
        /// closest such point for each of its segments.
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        /// <remarks>
        /// This currently does not always take into account any Pen width.
        /// </remarks>
        public override bool GetNearestIntersectionPoint(PointF p1, PointF p2, out PointF result)
        {
            RectangleF bounds = Bounds;
            float      num    = PenWidth / 2f;
            float      num2   = 1E+21f;
            PointF     pointF = default(PointF);

            checked
            {
                PointF result2;
                if (Style == GoPolygonStyle.Bezier)
                {
                    for (int i = 3; i < myPointsCount; i += 3)
                    {
                        PointF point  = GetPoint(i - 3);
                        PointF point2 = GetPoint(i - 2);
                        if (i + 3 >= myPointsCount)
                        {
                            i = myPointsCount - 1;
                        }
                        PointF point3 = GetPoint(i - 1);
                        PointF point4 = GetPoint(i);
                        if (GoStroke.BezierNearestIntersectionOnLine(point, point2, point3, point4, p1, p2, num, out result2))
                        {
                            float num3 = (result2.X - p1.X) * (result2.X - p1.X) + (result2.Y - p1.Y) * (result2.Y - p1.Y);
                            if (num3 < num2)
                            {
                                num2   = num3;
                                pointF = result2;
                            }
                        }
                    }
                }
                else
                {
                    for (int j = 0; j < PointsCount; j++)
                    {
                        PointF a = GoShape.ExpandPointOnEdge(GetPoint(j), bounds, num);
                        PointF b = GoShape.ExpandPointOnEdge(GetPoint((j + 1 < PointsCount) ? (j + 1) : 0), bounds, num);
                        if (GoStroke.NearestIntersectionOnLine(a, b, p1, p2, out result2))
                        {
                            float num4 = (result2.X - p1.X) * (result2.X - p1.X) + (result2.Y - p1.Y) * (result2.Y - p1.Y);
                            if (num4 < num2)
                            {
                                num2   = num4;
                                pointF = result2;
                            }
                        }
                    }
                }
                result = pointF;
                return(num2 < 1E+21f);
            }
        }
Пример #3
0
        /// <summary>
        /// The closest point of a cylinder that intersects with a given line
        /// is the closest such point of each two line segments and two ellipses.
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override bool GetNearestIntersectionPoint(PointF p1, PointF p2, out PointF result)
        {
            RectangleF bounds = Bounds;
            float      shift  = PenWidth / 2f;

            PointF[]   points = getPoints();
            PointF     a      = GoShape.ExpandPointOnEdge(points[0], bounds, shift);
            PointF     b      = GoShape.ExpandPointOnEdge(points[1], bounds, shift);
            PointF     a2     = GoShape.ExpandPointOnEdge(points[2], bounds, shift);
            PointF     b2     = GoShape.ExpandPointOnEdge(points[3], bounds, shift);
            float      num    = 1E+21f;
            PointF     pointF = default(PointF);
            RectangleF rect;
            RectangleF rect2;
            float      startAngle;
            float      startAngle2;

            if (Orientation == Orientation.Vertical)
            {
                rect        = new RectangleF(bounds.X, bounds.Y, bounds.Width, MinorRadius * 2f);
                rect2       = new RectangleF(bounds.X, bounds.Y + bounds.Height - MinorRadius * 2f, bounds.Width, MinorRadius * 2f);
                startAngle  = 180f;
                startAngle2 = 0f;
            }
            else
            {
                rect        = new RectangleF(bounds.X, bounds.Y, MinorRadius * 2f, bounds.Height);
                rect2       = new RectangleF(bounds.X + bounds.Width - MinorRadius * 2f, bounds.Y, MinorRadius * 2f, bounds.Height);
                startAngle  = 90f;
                startAngle2 = 270f;
            }
            if (GoEllipse.NearestIntersectionOnArc(rect, p1, p2, out PointF result2, startAngle, 180f))
            {
                float num2 = (result2.X - p1.X) * (result2.X - p1.X) + (result2.Y - p1.Y) * (result2.Y - p1.Y);
                if (num2 < num)
                {
                    num    = num2;
                    pointF = result2;
                }
            }
            if (Orientation == Orientation.Horizontal)
            {
                if (GoEllipse.NearestIntersectionOnArc(rect2, p1, p2, out result2, 270f, 90f))
                {
                    float num3 = (result2.X - p1.X) * (result2.X - p1.X) + (result2.Y - p1.Y) * (result2.Y - p1.Y);
                    if (num3 < num)
                    {
                        num    = num3;
                        pointF = result2;
                    }
                }
                if (GoEllipse.NearestIntersectionOnArc(rect2, p1, p2, out result2, 0f, 90f))
                {
                    float num4 = (result2.X - p1.X) * (result2.X - p1.X) + (result2.Y - p1.Y) * (result2.Y - p1.Y);
                    if (num4 < num)
                    {
                        num    = num4;
                        pointF = result2;
                    }
                }
            }
            else if (GoEllipse.NearestIntersectionOnArc(rect2, p1, p2, out result2, startAngle2, 180f))
            {
                float num5 = (result2.X - p1.X) * (result2.X - p1.X) + (result2.Y - p1.Y) * (result2.Y - p1.Y);
                if (num5 < num)
                {
                    num    = num5;
                    pointF = result2;
                }
            }
            if (GoStroke.NearestIntersectionOnLine(a, b, p1, p2, out result2))
            {
                float num6 = (result2.X - p1.X) * (result2.X - p1.X) + (result2.Y - p1.Y) * (result2.Y - p1.Y);
                if (num6 < num)
                {
                    num    = num6;
                    pointF = result2;
                }
            }
            if (GoStroke.NearestIntersectionOnLine(a2, b2, p1, p2, out result2))
            {
                float num7 = (result2.X - p1.X) * (result2.X - p1.X) + (result2.Y - p1.Y) * (result2.Y - p1.Y);
                if (num7 < num)
                {
                    num    = num7;
                    pointF = result2;
                }
            }
            result = pointF;
            return(num < 1E+21f);
        }
Пример #4
0
        /// <summary>
        /// Find the intersection points of a pie and the infinite line p1-p2
        /// that is closest to point p1.
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override bool GetNearestIntersectionPoint(PointF p1, PointF p2, out PointF result)
        {
            RectangleF a   = Bounds;
            float      num = PenWidth / 2f;

            GoObject.InflateRect(ref a, num, num);
            float num2       = a.Width / 2f;
            float num3       = a.Height / 2f;
            float num4       = a.X + num2;
            float num5       = a.Y + num3;
            float num6       = p1.X - num4;
            float num7       = p1.Y - num5;
            float startAngle = StartAngle;
            float sweepAngle = SweepAngle;
            float num8       = startAngle + sweepAngle;

            if (num8 > 360f)
            {
                num8 -= 360f;
            }
            bool  result2 = false;
            float num9    = 1E+21f;

            result = default(PointF);
            if (-0.01f < num6 && num6 < 0.01f)
            {
                num6 = 0.01f;
            }
            if (-0.01f < num7 && num7 < 0.01f)
            {
                num7 = 0.01f;
            }
            PointF result3;

            if (sweepAngle >= 360f)
            {
                if (GoEllipse.NearestIntersectionOnEllipse(a, p1, p2, out result3))
                {
                    float num10 = (p1.X - result3.X) * (p1.X - result3.X) + (p1.Y - result3.Y) * (p1.Y - result3.Y);
                    if (num10 < num9)
                    {
                        result2 = true;
                        result  = result3;
                        num9    = num10;
                    }
                }
            }
            else if (sweepAngle + startAngle > 360f)
            {
                if (GoEllipse.NearestIntersectionOnArc(a, p1, p2, out result3, startAngle, 360f - startAngle))
                {
                    float num11 = (p1.X - result3.X) * (p1.X - result3.X) + (p1.Y - result3.Y) * (p1.Y - result3.Y);
                    if (num11 < num9)
                    {
                        result2 = true;
                        result  = result3;
                        num9    = num11;
                    }
                }
                if (GoEllipse.NearestIntersectionOnArc(a, p1, p2, out result3, 0f, sweepAngle - (360f - startAngle)))
                {
                    float num12 = (p1.X - result3.X) * (p1.X - result3.X) + (p1.Y - result3.Y) * (p1.Y - result3.Y);
                    if (num12 < num9)
                    {
                        result2 = true;
                        result  = result3;
                        num9    = num12;
                    }
                }
            }
            else if (GoEllipse.NearestIntersectionOnArc(a, p1, p2, out result3, startAngle, sweepAngle))
            {
                float num13 = (p1.X - result3.X) * (p1.X - result3.X) + (p1.Y - result3.Y) * (p1.Y - result3.Y);
                if (num13 < num9)
                {
                    result2 = true;
                    result  = result3;
                    num9    = num13;
                }
            }
            PointF pointAtAngle = GetPointAtAngle(startAngle);

            if (GoStroke.NearestIntersectionOnLine(new PointF(num4, num5), pointAtAngle, p1, p2, out result3))
            {
                float num14 = (p1.X - result3.X) * (p1.X - result3.X) + (p1.Y - result3.Y) * (p1.Y - result3.Y);
                if (num14 < num9)
                {
                    result2 = true;
                    result  = result3;
                    num9    = num14;
                }
            }
            PointF pointAtAngle2 = GetPointAtAngle(num8);

            if (GoStroke.NearestIntersectionOnLine(new PointF(num4, num5), pointAtAngle2, p1, p2, out result3))
            {
                float num15 = (p1.X - result3.X) * (p1.X - result3.X) + (p1.Y - result3.Y) * (p1.Y - result3.Y);
                if (num15 < num9)
                {
                    result2 = true;
                    result  = result3;
                    num9    = num15;
                }
            }
            return(result2);
        }
Пример #5
0
        /// <summary>
        /// Find the intersection point of the elliptical path defined by rectangle rect and an infinite
        /// line p1-p2 that is closest to point p1.
        /// </summary>
        /// <param name="rect"></param>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static bool NearestIntersectionOnEllipse(RectangleF rect, PointF p1, PointF p2, out PointF result)
        {
            if (rect.Width == 0f)
            {
                return(GoStroke.NearestIntersectionOnLine(new PointF(rect.X, rect.Y), new PointF(rect.X, rect.Y + rect.Height), p1, p2, out result));
            }
            if (rect.Height == 0f)
            {
                return(GoStroke.NearestIntersectionOnLine(new PointF(rect.X, rect.Y), new PointF(rect.X + rect.Width, rect.Y), p1, p2, out result));
            }
            float num  = rect.Width / 2f;
            float num2 = rect.Height / 2f;
            float num3 = rect.X + num;
            float num4 = rect.Y + num2;
            float num5 = 9999f;

            if (p1.X > p2.X)
            {
                num5 = (p1.Y - p2.Y) / (p1.X - p2.X);
            }
            else if (p1.X < p2.X)
            {
                num5 = (p2.Y - p1.Y) / (p2.X - p1.X);
            }
            if (Math.Abs(num5) < 9999f)
            {
                float num6 = p1.Y - num4 - num5 * (p1.X - num3);
                if (num * num * (num5 * num5) + num2 * num2 - num6 * num6 < 0f)
                {
                    result = default(PointF);
                    return(false);
                }
                float num7  = (float)Math.Sqrt(num * num * (num5 * num5) + num2 * num2 - num6 * num6);
                float num8  = (0f - num * num * num5 * num6 + num * num2 * num7) / (num2 * num2 + num * num * (num5 * num5)) + num3;
                float num9  = (0f - num * num * num5 * num6 - num * num2 * num7) / (num2 * num2 + num * num * (num5 * num5)) + num3;
                float num10 = num5 * (num8 - num3) + num6 + num4;
                float num11 = num5 * (num9 - num3) + num6 + num4;
                float num12 = Math.Abs((p1.X - num8) * (p1.X - num8)) + Math.Abs((p1.Y - num10) * (p1.Y - num10));
                float num13 = Math.Abs((p1.X - num9) * (p1.X - num9)) + Math.Abs((p1.Y - num11) * (p1.Y - num11));
                if (num12 < num13)
                {
                    result = new PointF(num8, num10);
                }
                else
                {
                    result = new PointF(num9, num11);
                }
            }
            else
            {
                float num14 = num2 * num2;
                float num15 = num * num;
                float num16 = p1.X - num3;
                float num17 = num14 - num14 / num15 * (num16 * num16);
                if (num17 < 0f)
                {
                    result = default(PointF);
                    return(false);
                }
                float num18 = (float)Math.Sqrt(num17);
                float num19 = num4 + num18;
                float num20 = num4 - num18;
                float num21 = Math.Abs(num19 - p1.Y);
                float num22 = Math.Abs(num20 - p1.Y);
                if (num21 < num22)
                {
                    result = new PointF(p1.X, num19);
                }
                else
                {
                    result = new PointF(p1.X, num20);
                }
            }
            return(true);
        }