Angle between vectors

Started by
9 comments, last by darkzim 18 years, 10 months ago
I'm trying to get an angle between two vectors for rotating my AI to face the player in my game, but I only have math up to Algebra 1 so I need a little help. From what I've read in "Game Coding Complete" I need to take the dot product of the two vectors, perform some kind of archcosine thing, and then take the cross product of the two vectors to figure out which way to turn. So is this what I have to do? And what is the archcosine function (the book seems to assume you've had trig) and how do I use it? Sorry if this is a dumb question.

---------------------------------darkzim

Advertisement
Dot Product exactly.
The dot product gives the cosine of the angle of two vectors. If you want the angle you have to take the 'inverse cosine' which is usually called 'acos' because it is not actually inverted in a mathematical sense.

The key insight may be that:
acos( cos( a ) ) = a


You also have asin and atan and some others.

Greetz,

Illco
If you only require a 2D angle to face, i.e if all your characters are on the same height level, then you can...

Get the direction vector:

Vec3 dir = destLoc - srcLoc;

And...

float fAngle = atanf( dir.y, dir.x );

Which will give you the angle to face
In the above post, its assuming Z is facing UP in the world..
If Y is up in your world use...

float fAngle = atanf( dir.z, dir.x );
Illco forgets to mention it only works for unit-length vectors.

The real formula is:

dot(A, B) = length(A) * length(B) * cos(theta)

which leads to:

theta = acosf( dot(A, B) / length(A) * length(B) )

So if your vectors are of unit-length (length = 1), then you can of course skip the divider.

Best regards,
Roq
Sorry if this is another dumb question :( but when I tried to code in the 2D method above, my compiler said that atanf only accepted 1 arguement, so how am i supposed to pass in x and z?

P.s thx for all the fast replies

---------------------------------darkzim

First it is about acos not atan. And second, as correctly pointed out, you should take the length of the vectors. So first you compute the dot product of A and B which is a single number D. Then multiply the lengths of both vectors, which is also a single number L. Then take acos( D / L ).
Yes, and to supply Illco:

Given a vector V, the length of V is:

length(V) = sqrt( V.x*V.x + V.y*V.y + V.z*V.z )

:)
For 2d vectors of arbitrary length, you can also use:

angle = atan2(a.PerpDot(b), a.Dot(b));

Which gives you the signed angle. In 3d:

angle = atan2(Length(a.Cross(b)), a.Dot(b));

Here the angle is unsigned; you'll need a frame of reference to determine which 'direction' the angle is in.

This topic is closed to new replies.

Advertisement