Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Closest point From a Ray (a line), to the spline
#1
Hello Smile

I Wonder if you have already a function who find the closest position from a Ray to your spline.

You have the curvySpline.GetNearestPointTF(worldPos, out closestPosition);

I could test every point on the Ray (or iterate randomly with more and more acuracy), but I a sure there is a better & opti way of doing it with Math.
How could I do with your plugin ?

Thanks Smile
Reply
#2
Hi,
Here is an implementation of the method you want. I need to work on it more before putting it in a release, but if this can save you some time, here it go:
In CurvySplineSegment.cs

Code:
public float GetNearestPointF(Ray ray, out Vector3 nearestPointOnRay) { #if CURVY_SANITY_CHECKS Assert.IsTrue(CacheSize >= 0, "[Curvy] CurvySplineSegment has unintialized cache. Call Refresh() on the CurvySpline it belongs to."); #endif int ui = CacheSize + 1; float nearestDistSqr = float.MaxValue; float distSqr; int nearestIndex = 0; // get the nearest index for (int i = 0; i < ui; i++) { distSqr = DistanceToLine(ray, Approximation[i]); if (distSqr <= nearestDistSqr) { nearestDistSqr = distSqr; nearestIndex = i; } } // collide p against the lines build by the index int leftIdx = (nearestIndex > 0) ? nearestIndex - 1 : -1; int rightIdx = (nearestIndex < CacheSize) ? nearestIndex + 1 : -1; nearestPointOnRay = NearestPointOnRay(ray, Approximation[nearestIndex]); float lfrag = 0; float rfrag = 0; float ldistSqr = float.MaxValue; float rdistSqr = float.MaxValue; if (leftIdx > -1) ldistSqr = DTMath.LinePointDistanceSqr(Approximation[leftIdx], Approximation[nearestIndex], nearestPointOnRay, out lfrag); if (rightIdx > -1) rdistSqr = DTMath.LinePointDistanceSqr(Approximation[nearestIndex], Approximation[rightIdx], nearestPointOnRay, out rfrag); float stepSize = 1f / CacheSize; // return the nearest collision if (ldistSqr < rdistSqr) return getApproximationLocalF(leftIdx) + lfrag * stepSize; else return getApproximationLocalF(nearestIndex) + rfrag * stepSize; }        public static float DistanceToLine(Ray ray, Vector3 point)        {            return Vector3.Cross(ray.direction, point - ray.origin).magnitude;        }        public static Vector3 NearestPointOnRay(Ray ray, Vector3 point)        {            Vector3 delta = point - ray.origin;            float distance = Mathf.Max(0, Vector3.Dot(delta, ray.direction));            return ray.origin + ray.direction * distance;        }

In CurvySpline.cs

Code:
       public float GetNearestPointTF(Ray ray, out Vector3 nearestPoint, [CanBeNull] out CurvySplineSegment nearestSegment, out float nearestSegmentF, int startSegmentIndex = 0, int stopSegmentIndex = -1)        { #if CURVY_SANITY_CHECKS            DoSanityChecks(); #endif            nearestPoint = Vector3.zero;            if (Count == 0)            {                nearestSegment = null;                nearestSegmentF = -1;                return -1;            }            // for each segment, get the distance to it's approximation points            float distSqr = float.MaxValue;            float resF = 0;            CurvySplineSegment resSeg = null;            if (stopSegmentIndex == -1)                stopSegmentIndex = Count - 1;            startSegmentIndex = Mathf.Clamp(startSegmentIndex, 0, Count - 1);            stopSegmentIndex = Mathf.Clamp(stopSegmentIndex + 1, startSegmentIndex + 1, Count);            for (int i = startSegmentIndex; i < stopSegmentIndex; i++)            {                Vector3 nearestPointOnRay;                float f = this[i].GetNearestPointF(ray, out nearestPointOnRay);                Vector3 v = this[i].Interpolate(f);                float magSqr = (v - nearestPointOnRay).sqrMagnitude;                if (magSqr <= distSqr)                {                    resSeg = this[i];                    resF = f;                    nearestPoint = v;                    distSqr = magSqr;                }                //DrawPoint(v, Color.cyan);                //DrawPoint(nearestPointOnRay, Color.magenta);            }            nearestSegment = resSeg;            nearestSegmentF = resF;            // return the nearest            return resSeg.LocalFToTF(resF);        }         public float GetNearestPointTF(Ray ray, out Vector3 nearest, int startSegmentIndex = 0, int stopSegmentIndex = -1)         { #if CURVY_SANITY_CHECKS             DoSanityChecks(); #endif             CurvySplineSegment segement;             float f;             return GetNearestPointTF(ray, out nearest, out segement, out f, startSegmentIndex, stopSegmentIndex);         }         public float GetNearestPointTF(Ray ray, int startSegmentIndex = 0, int stopSegmentIndex = -1)         { #if CURVY_SANITY_CHECKS             DoSanityChecks(); #endif             Vector3 v;             return GetNearestPointTF(ray, out v, startSegmentIndex, stopSegmentIndex);         }         public float GetNearestPointTF(Ray ray, out Vector3 nearest)         { #if CURVY_SANITY_CHECKS             DoSanityChecks(); #endif             return GetNearestPointTF(ray, out nearest, 0, -1);         }
Please consider leaving a review for Curvy Splines, this helps immensely. Thank you.
Reply
#3
Wow, honestly, that far from I excpected, you just give me the good method, without any compile error at the first implementation, in less than a day, and it work ! Wow you are amazing ! Sincerly !
Reply
#4
Thanks a lot, you are making me shy Big Grin
But to be honest, I had that method already implemented. I just didn't take the time yet to test the s*** out of it, optimize it and document it. Once this is done, it will be included in the next Curvy update.
Please consider leaving a review for Curvy Splines, this helps immensely. Thank you.
Reply
#5
you're welcome Smile

oh, you should add another out Vector3, if I want to have also the closest point in the line
Reply
#6
noted, thanks
Please consider leaving a review for Curvy Splines, this helps immensely. Thank you.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Spline Issue Leading to Unity Freeze Pankaj09 1 461 08-24-2026, 11:28 PM
Last Post: _Aka_
  Connecting Multiple Spline Nodes Issue Ritesh Kadam 1 407 08-22-2026, 11:24 PM
Last Post: _Aka_
  Spline Spots from 2 samples. BitBlit 8 1,649 06-30-2026, 11:49 AM
Last Post: _Aka_
  Best way to duplicate a spline with an offset Kapistijn 8 3,055 04-12-2026, 03:18 PM
Last Post: _Aka_

Forum Jump: