I'll expand a bit on TravisG's comment and give another answer, making use of the fact that your question had the "2D" tag.
You can get the angle between two vectors using the dot product, but you can't get the signed angle between two vectors using it. Put another way, if you want to turn a character over time towards a point, the dot product will get you how much to turn but not which direction. There is another simple formula, however, which is very useful when combined with the dot product. Not only do you have
dot(A,B) = |A| * |B| * cos(angle)
You can also have another formula (whose name I made up for political correctness):
pseudoCross(A,B) = |A| * |B| * sin(angle)
where if A=(a,b), B=(x,y), then pseudoCross(A,B) is defined to be the third component of the cross product (a,b,0)x(x,y,0). In other words:
a*x+b*y = |A| * |B| * cos(angle)
-b*x+a*y = |A| * |B| * sin(angle)
The full signed angle is then angle=atanfull(-b*x+a*y,a*x+b*y)
(atanfull or atan2 functions forgive you if you pass in non-normalized values).
If A and B are normalized, that is, if |A|=|B|=1
, these are simply:
a*x+b*y = cos(angle)
-b*x+a*y = sin(angle)
For a deeper explanation, note that the equations above can be expressed by the matrix equation:
[ a,b] [x] [cos(angle)]
[-b,a] * [y] = [sin(angle)]
But a and b can be expressed as a=cos(ang1)
, b=sin(ang1)
, for some value ang1
(not angle
). Therefore, the matrix on the left is a rotation matrix which rotates the vector (x,y) by the amount -ang1. This is equivalent to switching into a frame of reference where the unit vector "A" is treated as the vector/axis (1,0)! So then just by drawing the unit circle/right triangle in this frame, you can see why the resulting vector of that product is (cos(angle),sin(angle)).
If you write (a,b) and (x,y) in polar form, and apply the angle difference formulas cos(l)*cos(m)+sin(l)*sin(m)=cos(l-m)
and sin(l)*cos(m)-cos(l)*sin(m)=sin(l-m)
, you re-express that the sines/cosines are given by this product, since (l-m)=angle. Alternatively, those identities could be used to see why the linear product given above rotates a vector.
All these identities mean that you rarely need angles. Because angles can be weird - radian/degrees, conventions for inverse sine/cosine, the fact that they repeat every 2*pi - this can actually be more useful and save you a bunch of "if(ang<180)" etc logic.