Thursday, July 7, 2016

How can I calculate the angle and proper turn direction between two 2D vectors?


I am working on some movement AI where there are no obstacles and movement is restricted to the XY plane. I am calculating two vectors, v, the facing direction of ship 1, and w, the vector pointing from the position of ship 1 to ship 2.


I am then calculating the angle between these two vectors using the formula


arccos((v · w) / (|v| · |w|))

The problem I'm having is that arccos only returns values between 0° and 180°. This makes it impossible to determine whether I should turn left or right to face the other ship.


Is there a better way to do this?




Answer



It's much faster to use a 2d cross-product. No costly trig function involved.


b2Vec2 target( ... );
b2Vec2 heading( ... );

float cross = b2Cross( target, heading );

if( cross == -0.0f )
// turn around


if( cross == 0.0f )
// already traveling the right direction

if( cross < 0.0f)
// turn left

if( cross > 0.0f)
// turn right

If you still need the actual angles I recommend using atan2. atan2 will give you the absolute angle of any vector. To get the relative angle between any to vectors, calcuate their absolute angles and use simple subtraction.



b2Vec2 A(...);
b2Vec2 B(...);

float angle_A = std::atan2(A.y,A.x);
float angle_B = B.GetAngle(); // Box2D already figured this out for you.

float angle_from_A_to_B = angle_B-angle_A;
float angle_from_B_to_A = angle_A-angle_B;

No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...