Any way to get the interpolation ratio of a BezierKnot from its index on a Spline?

Basically I’m looking for the opposite of this: [Splines] How to determine/evaluate if a knot has been passed/reached? - Unity Engine - Unity Discussions

I want to adjust a BezierKnot’s position based on its relative distance on the Spline. As far as I can tell, you can convert from an interpolation ratio to an index, but not the other way around. The workaround I’ve come up with is to take the knot’s position, use SplineUtility.GetNearestPoint to convert that position to a ratio, then use that ratio in my evaluation.

SplineUtility.GetNearestPoint(m_Spline, instanceKnots[j].Position, out nearPos, out nearPosT);
 w = m_Widths[0].Evaluate(m_Spline, nearPosT, PathIndexUnit.Normalized, new UnityEngine.Splines.Interpolators.LerpFloat());

However this seems potentially expensive to run, and also inaccurate since the nearest point is just an estimate. Is there an official function I’m missing that’ll handle this?

Here’s what I used to get the relative distance of a knot on the spline. Just pass in the knot’s index.
Then, relative to that knot you can get a new position and T with GetPointAtLinearDistance(). Positive distance moves towards the next knot and negative distance towards the previous.
(See: Class SplineUtility | Splines | 1.0.1)

var knotDistance = _currentSpline.ConvertIndexUnit(knotIndex, PathIndexUnit.Knot, PathIndexUnit.Distance);
var knotT = knotDistance / _currentSpline.GetLength();
var relativePositionOnSpline = _currentSpline.GetPointAtLinearDistance(knotT, distance, out var relativePointT);

Hope it helps!

For futur reference, my previous answer was not correct. GetPointAtLinearDistance returns a position at a distance in a direct line from “fromtT”, not along the spline.

EvaluatePosition would be more correct. Example to get the position on the spline between to knots:

var previousT = currentSpline.ConvertIndexUnit(previousKnotIdx, PathIndexUnit.Knot, PathIndexUnit.Normalized);
var nextT = currentSpline.ConvertIndexUnit(nextKnotIdx, PathIndexUnit.Knot, PathIndexUnit.Normalized);
var midT= (nextT + previousT) / 2;
var midPosition = currentSpline.EvaluatePosition(midT);