/// <summary> /// Determine the segment index of the closest point on a segmentwise-defined line to a test point /// </summary> /// <param name="point">The test point</param> /// <param name="linePointList">List of points defining the line</param> /// <param name="extrusionAmountAbs">Absolute value of the extrusion distance</param> internal static int ClosestIndexAlongSegmentwiseLine(Vector2 point, SegmentwiseLinePointListUV linePointList, float extrusionAmountAbs) { float fractionAlongClosestSegment; Vector2 closestSegmentDifference; int closestSegmentIndex; ClosestPointAlongSegmentwiseLine(point, linePointList, extrusionAmountAbs, GetVector, GetAverage, out fractionAlongClosestSegment, out closestSegmentDifference, out closestSegmentIndex); return(closestSegmentIndex); }
/// <summary> /// Determines if an extruded point is closer to a line (on a segment-by-segment basis) than the extrusion amount. /// </summary> /// <param name="extrudedPoint">Extruded test point</param> /// <param name="linePointList">List of points defining the line</param> /// <param name="extrusionAmount">The extrusion amount</param> internal static bool IsCloserThanExtrusionDistance_Segmentwise(ExtrudedPointUV extrudedPoint, SegmentwiseLinePointListUV linePointList, float extrusionAmount) { var linePoints = linePointList.Points; var linePointsMaximumDelta = linePointList.MaxSegmentDistance; var numSegments = linePoints.Count - 1; Vector2 point = extrudedPoint.Point; var segmentIndex = Math.Max(0, Math.Min(numSegments - 1, extrudedPoint.LinePointSegmentIndex)); var segmentIndex2 = Math.Max(0, Math.Min(numSegments - 1, extrudedPoint.LinePointSegmentIndex2)); bool isCloser = false; var extrusionAmountAbs = Mathf.Abs(extrusionAmount); var extrusionAmountSquared = extrusionAmount * extrusionAmount; //We'll look every *numSteps* points to see what's closest. We will increase it if the line point is much further away than the extrusion distance. int numSteps = 1; for (int i = 0; i < numSegments; i += numSteps) { if (i != segmentIndex && i != segmentIndex2) { isCloser = LineSegmentUtil.IsPointWithinDistanceOfSegment(linePoints[i].Point, linePoints[i + 1].Point, point, extrusionAmountSquared); } if (isCloser) { break; } else { var distanceDiff = (linePoints[i].Point - point).magnitude - extrusionAmountAbs; numSteps = Mathf.FloorToInt(Mathf.Max(1f, distanceDiff / linePointsMaximumDelta)); } } return(isCloser); }
/// <summary> /// Determine the closest point on a segmentwise-defined line to a test point /// </summary> /// <param name="point">The test point</param> /// <param name="linePointList">List of points defining the line</param> /// <param name="extrusionAmountAbs">Absolute value of the extrusion distance</param> /// <param name="fractionAlongClosestSegment">Fraction along segment containing the closest point.</param> /// <param name="closestSegmentDifference">Start-to-end vector of the segment containing the closest point</param> /// <param name="closestSegmentIndex">Index of the closest segment.</param> internal static LinePointUV ClosestPointAlongSegmentwiseLine(Vector2 point, SegmentwiseLinePointListUV linePointList, float extrusionAmountAbs, out float fractionAlongClosestSegment, out Vector2 closestSegmentDifference, out int closestSegmentIndex) { return(ClosestPointAlongSegmentwiseLine(point, linePointList, extrusionAmountAbs, GetVector, GetAverage, out fractionAlongClosestSegment, out closestSegmentDifference, out closestSegmentIndex)); }