Here's a handy little function you can use to get the angle between vectors in a signed format (+/-). You'll pass in your source vector (which is generally the way something is facing), the destination vector (the way something is wanting to turn to), and an angle that is 90 degrees to the right of the destination angle (we'll call it 'DestsRight'). To get an angle 90 degrees to the right of the destination angle you may need to use a Cross Product, which we'll be going over in the this blog post.
float GetSignedAngleBetweenVectors( const Vector3& Source, const Vector3& Dest, const Vector3& DestsRight ) { // We make sure all of our vectors are unit length Vector3 SourceCopy = Source; SourceCopy.Unitize(); Vector3 DestCopy = Dest; DestCopy.Unitize(); Vector3 DestsRightCopy = DestsRight; DestsRightCopy.Unitize(); float forwardDot = Vector3.Dot( SourceCopy, DestCopy ); float rightDot = Vector3.Dot( SourceCopy, DestsRightCopy ); // Make sure we stay in range no matter what, so Acos // doesn't fail later if ( forwardDot < -1.0f ) { forwardDot = -1.0f; } else if ( forwardDot > 1.0f ) { forwardDot = 1.0f; } float angleBetween = acos( forwardDot ); if ( rightDot < 0.0f ) { angleBetween *= - 1.0f; } return angleBetween; }
If we were to use this above function with these vectors:
The dot between S and D would be greater than 0, dot between S and R would be less than 0, so the final result angle would be negative, so we would know if D is the way we're facing we'd need to turn left to get to S. The dot between S and D would be greater than 0, dot between S and R would be greater than 0, so the final result angle would be positive, so we would know if D is the way we're facing we'd need to turn right to get to S.
I'm too lazy right now to do a math proof of the above function, so you'll just need to trust me that it works (I've used something like this in production code).
No comments:
Post a Comment