/// <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); }
/// <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); } }
/// <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); }
/// <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); }
/// <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); }