Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

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

Discussion in 'World Building' started by m0nkeybl1tz, Jul 19, 2023.

  1. m0nkeybl1tz

    m0nkeybl1tz

    Joined:
    Feb 10, 2013
    Posts:
    35
    Basically I'm looking for the opposite of this: https://forum.unity.com/threads/spl...ate-if-a-knot-has-been-passed-reached.1383816

    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.

    Code (CSharp):
    1. SplineUtility.GetNearestPoint(m_Spline, instanceKnots[j].Position, out nearPos, out nearPosT);
    2.  w = m_Widths[0].Evaluate(m_Spline, nearPosT, PathIndexUnit.Normalized, new UnityEngine.Splines.Interpolators.LerpFloat());
    3.  
    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?
     
  2. ytremblay38

    ytremblay38

    Joined:
    Apr 24, 2018
    Posts:
    2
    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: https://docs.unity3d.com/Packages/c...0_System_Single_System_Single_System_Single__)

    Code (CSharp):
    1. var knotDistance = _currentSpline.ConvertIndexUnit(knotIndex, PathIndexUnit.Knot, PathIndexUnit.Distance);
    2. var knotT = knotDistance / _currentSpline.GetLength();
    3. var relativePositionOnSpline = _currentSpline.GetPointAtLinearDistance(knotT, distance, out var relativePointT);
    Hope it helps!
     
    Last edited: Aug 26, 2023
  3. ytremblay38

    ytremblay38

    Joined:
    Apr 24, 2018
    Posts:
    2
    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:
    Code (CSharp):
    1. var previousT = currentSpline.ConvertIndexUnit(previousKnotIdx, PathIndexUnit.Knot, PathIndexUnit.Normalized);
    2. var nextT = currentSpline.ConvertIndexUnit(nextKnotIdx, PathIndexUnit.Knot, PathIndexUnit.Normalized);
    3. var midT= (nextT + previousT) / 2;
    4. var midPosition = currentSpline.EvaluatePosition(midT);