Search code examples
vectorunreal-engine4vector-graphics

Vector Math. Clamp point to within x,y of spline?


could you please help me with this vector math problem?

ProposedPoint, closest SplinePoint, and spline Up Vector create a plane

I have a game actor Camera_Rail that has one spline. Every point on the spline has an Up vector and Right vector, creating a perpendicular plane. Together, the spline and X,Y bounds describe a boxy noodle in space.

I would like a function: ClampPointWithinBounds(Spline, X, Y, ProposedPoint) returns ClampedPoint

How to calculate ClampedPoint

This is my plan, but there are some ??? :

  1. Finds the closest SplinePoint to ProposedPoint (done)
  2. Converts ProposedPoint to ProposedPoint2D with SplinePoint at 0,0 (???)
  3. Clamps ProposedPoint2d to X,Y bounds (done)
  4. Convert ClampedPoint2d to ClampedPoint in 3d and return. (???)

Alternatively, I could compute a ClampingVector directly in 3d space, but I don't have a plan for that.

How can I convert from 3d<->2d and back, and is there a better way? I'm using UE4.

Thank you!


Solution

  • "Finds the closest SplinePoint to ProposedPoint (done)." We will call these Vector3's SP and PP respectively.

    A circular/spherical bounds of radius R is easiest: P = (SP - PP).Normalize() * R; or expanded:

    L = Sqrt((SP.X - PP.X) * (SP.X - PP.X) + (SP.Y - PP.Y) * (SP.Y - PP.Y) + (SP.Z - PP.Z) * (SP.Z - PP.Z));
    P = ((SP.X - PP.X)/L,(SP.Y - PP.Y)/L,(SP.Z - PP.Z)/L) * R;
    

    For clamped bounds having extents, 1/2 of box size, of (X1,Y1,Z1), use R = X1 * X1 + Y1 * Y1 + Z1 * Z1, the furthest distance possible.

    The final clamped result = (Min(Abs(P.X),X1) * Sign(P.X), Min(Abs(P.Y),Y1) * Sign(P.Y), A.Z = Min(Abs(P.Z),Z1) * Sign(P.Z))

    For 2D, I would consider using Trig functions:

    P = (SP - PP);// ignoring Z
    Ang = ATan2(P.Y, P.X);
    X = X1 * Cos(Ang);
    Y = Y1 * Sin(Ang);
    

    The overhead of the trig functions is not worth extending into 3D. As a single Sqrt() call is usually quicker than the multiple trig calls required in 3D.