Angle between Vectors
If two vectors are of unit length, the cosine of the anlge between them is same as the dot product of the two vectors: \(\cos(\theta) = \vec{A} \cdot \vec{B} \). If the vectors are not of unit length, the dot product needs to be divided by the product of the vectors lengths: \(\cos(\theta) = \frac{\vec{A} \cdot \vec{B}}{\|A\|\|B\|}\). This implies that the angle is the inverse cosine (arc cosine) of the dot product of two unit vectors.
$$ \theta = \cos^{-1}(\frac{\vec{A} \cdot \vec{B}}{\|A\| \|B\|}) = \cos^{-1}(\hat{A} \cdot \hat{B}) $$
The formula for finding the angle between two vectors is derived using the Law of cosines. To find out how the equation is actually derived, check out this video.
In the interactive demo above, ckick and drag the green and blue vectors. The dot product and angle between these vectors is printed on the top left of the demo. In the bottom left, there are checkboxes for forcing the vectors to be of unit length and showing the triangle which is used to find this angle.
When implementing this in code, keep in mind that finding the length of each vector needs to perform a square root. Check to see if the input vectors are of unit length, if they are avoid finding the magnitude. To see if a vector is unit length, check if the square magnitude is about 1 (use a small epsilon like 0.0001 to account for floating point errors).
float Angle(vec a, vec b) { float sqMagA = MagnitudeSq(a); float sqMagB = MagnitudeSq(b); assert(sqMagA != 0); assert(sqMagB != 0); float dot = Dot(a, b); if (abs(1 - sqMagA) < EPSILON && abs(1 - sqMagB) < EPSILON) { return acos(dot); } float length = sqrt(sqMagA) * sqrt(sqMagB); return acos(dot / length); }
Optimization
Finding the angle between two vectors is expensive, and can often be avoided. Instead of checking the angle between two vectors, the dot product between them can be checked. For example:
if (Angle(vec1, vec2) < Deg2Rad(60.0f))
The above code could instead be expressed using only a dot product! If two vectors are 60 degrees apart, the dot product between them will be the cosine of 60 degrees (1.0472 radians). \(cos(1.0472) = 0.49\). Checking the value of the dot product avoids the inverse cosine and two square roots required to find the angle. The above code can be expressed as:
if (Dot(vec1, vec2) < 0.49)