# How can I calculate the angle 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?

-

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

``````b2Vec2 target( ... );

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;
``````
-
After reading @Tetrad's answer I suppose you could combine a cross product and an `arccos`. This way you'll only use one trig function, but still have the actual angle. However I recommend against this optimization until you're sure you AI angle tracking is making a noticeable impact on your game's performance. – deft_code Jan 7 '11 at 16:09
the magnitude of the cross product vector gives you the sin of the angle between them, not the cos. So you need to use `arcsin`. – Tetrad Jan 7 '11 at 19:29
Yes, when converting between vectors and angles, atan2() is most definitely your friend. – bluescrn Jan 7 '11 at 23:30
Thanks! I've found that I actually don't really need the angle, grabbing the 2D cross product is simple enough for my needs. – Error 454 Jan 8 '11 at 2:59
If he's looking for the direction to steer, his `w` vector actually has all the information he needs. He should go in the direction of the `w` vector. The fact that it's "left" or "right" doesn't matter when you're working in vectors. – bobobobo Nov 25 '12 at 21:40

Use arcsin of the 2D cross product (i.e the z component of the cross product vector). That'll give you -90 to 90 which will let you know whether to go left or right.

Be careful because A cross B is not the same as B cross A.

Another strategy (but probably not as straight forward) is to calculate the "heading" of the two vectors using atan2 and then figuring out whether A pointing at X degrees needs to go left or right to go to B pointing at y degrees.

-
 Thank you for the response. To be clear for future browsers, taking the inverse sine of the magnitude of the 2d cross product would yield values between 0 and 90. Taking the sine of the z-component of the 2d cross product yields the desired results. – Error 454 Jan 8 '11 at 2:58 @Error 454, you're absolutely right, fixed my post. – Tetrad♦ Jan 8 '11 at 4:11

Use vectors to redirect the ship. This is how "steering behaviors" work -- you never need to calculate the angle, just use the vectors you have. This is computationally much cheaper.

The vector `w` (vector from Ship 1 to Ship 2) is all the information you need. Modify either ship 1's velocity vector or ship 1's acceleration vector (or even the heading vector directly) using a weighted version of `w`.

The magnitude of how far off ship 1 is off course (how badly v does not match up with w) can be found by using ( `1 - dot(v,w)` )

• (`dot(v,w)` is maximized when `v` and `w` line up exactly)
• (`1 - dot(v,w)`) gives 0 when `v` and `w` are completely lined up, provided `v` and `w` are normalized)
-

There is a simple way to find the absolute angle of a vector through normal geometry.

for example vector V = 2i - 3j;

absolute value of x coefficient = 2;

absolute value of y coefficient = 3;

angle = atan( 2 / 3 ); [ angle will be in between 0 to 90 ]

Based on quadrant angle will be changed.

if ( x coefficient < 0 and y coefficient > 0 ) then angle = 180-angle;

if ( x coefficient < 0 and y coefficient < 0 ) then angle = 180+angle;

if ( x coefficient > 0 and y coefficient < 0 ) then angle = 360-angle;

if ( x coefficient > 0 and y coefficient > 0 ) then angle = angle;

after finding angle of first and second vectors, just subtract first vector angle from second vector. Then you will get absolute angle between two vectors.

-
This is exactly what the atan2() function implements for you. :) – Nathan Reed Sep 30 '11 at 18:59