private MinDistanceAtTPair GetClosestTParameter(BezierTParameterRequest request, MinDistanceAtTPair _minDistanceAtT) { float mid = (request.startingT + request.endT) / 2.0f; // Base case for recursion. if ((request.endT - request.startingT) < request.thresholdT) { _minDistanceAtT.tParameter = mid; return(_minDistanceAtT); } // The two halves have param range [start, mid] and [mid, end]. We decide which one to use by using a midpoint param calculation for each section. float paramA = (request.startingT + mid) / 2.0f; float paramB = (mid + request.endT) / 2.0f; Vector3 posA = GetPoint(paramA); Vector3 posB = GetPoint(paramB); float distASq = (posA - request.pointToCheck).sqrMagnitude; float distBSq = (posB - request.pointToCheck).sqrMagnitude; if (distASq < distBSq) { request.endT = mid; _minDistanceAtT.minSqrDistance = distASq; } else { request.startingT = mid; _minDistanceAtT.minSqrDistance = distBSq; } // The (tail) recursive call. return(GetClosestTParameter(request, _minDistanceAtT)); }
public float GetTParameter(Vector3 _pointToCheck) { MinDistanceAtTPair result = new MinDistanceAtTPair(float.NaN, float.NaN); for (int i = 0; i < Spline.ControlPointCount - 1; i += 3) { BezierTParameterRequest request = new BezierTParameterRequest(_pointToCheck); result = GetClosestTParameter(request, result); } return(result.tParameter); }