Search Unity

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

Resolved Figure out whether a point is inside a Unity spline (new spline system)

Discussion in 'World Building' started by Wolfos, Oct 23, 2023.

  1. Wolfos

    Wolfos

    Joined:
    Mar 17, 2011
    Posts:
    946
    Hi all,

    I tackled this problem recently and since I couldn't find the solution on search engines, I figured I'd share my solution here where it's visible for all:

    Code (CSharp):
    1. /// <summary>
    2. /// Whether a point is inside a closed spline.
    3. /// </summary>
    4. /// <param name="point">A point, local to the spline's space</param>
    5. /// <param name="spline">Unity spline</param>
    6. /// <returns>Whether the point is inside the spline</returns>
    7. public static bool IsInsideSpline(float3 point, Spline spline)
    8. {
    9.     SplineUtility.GetNearestPoint(spline, point, out var splinePoint, out var t);
    10.     spline.Evaluate(t, out _, out var tangent, out _);
    11.  
    12.     var cross = math.cross(math.up(), math.normalize(tangent));
    13.     return math.dot(splinePoint - point, cross) < 0;
    14. }
    Note: this only works if a spline is drawn clockwise.
     
    Last edited: Oct 23, 2023
  2. malvladimiras

    malvladimiras

    Joined:
    Sep 13, 2023
    Posts:
    1
    Code (CSharp):
    1.     public static bool IsInsideSpline(float3 point, SplineContainer splineContainer, Bounds splineBounds, out Vector3 nearestPointInSpline)
    2.     {
    3.         Vector3 pointPositionLocalToSpline = splineContainer.transform.InverseTransformPoint(point);
    4.  
    5.         SplineUtility.GetNearestPoint(splineContainer.Spline, pointPositionLocalToSpline, out var splinePoint, out var t);
    6.         splinePoint.y = pointPositionLocalToSpline.y;
    7.  
    8.         if(Vector3.Distance(point, splineContainer.transform.TransformPoint(splineBounds.center)) < Vector3.Distance(splinePoint, splineBounds.center))
    9.         {
    10.             // If point is inside of the spline...
    11.             nearestPointInSpline = point;
    12.             return true;
    13.         }
    14.         else
    15.         {
    16.             nearestPointInSpline = splineContainer.transform.TransformPoint(splinePoint);
    17.             return false;
    18.         }
    19.     }
    I needed to move an Audio Emitter unto the listener inside of the spline area and this code seemed to have worked. Don't know how efficient it is, but since this is a related problem thought I would leave it here!
     
  3. Wolfos

    Wolfos

    Joined:
    Mar 17, 2011
    Posts:
    946
    This goes wrong when the spline's shape is concave. The dot product in my implementation is what resolves this but that means it relies on the flow direction of the spline.
     
    Last edited: Nov 18, 2023