Angle Between Two Vectors with Cross Product
There are situations when you need to find out the angle between two vectors and the only thing you know are vectors coordinates. The same forma is used for 2D vectors and 3D vectors as well.
So there are a few concepts that we should be familiar with:
1) Cross Product
2) Dot Product
3) Vector Magnitude
4) Some geometry
The basic formula that we will use to find the angle is based on the magnitude of a cross product:
Ok but where does this formula come from? The demonstration is pretty simple but messy. First compute the cross product using Sarrus rule(this is how I “remember” the ugly formula for the cross product):
Now the next step is to write the magnitude for the cross product
As you might have guessed , we expand the parantheses and a long calculus is waiting to be done. So in the end you should have something like this:
We can observe three dot products above. First two are very easy to spot and the third one is the geometric dot product squared:
Hint! The magnitude of a cross product of two vectors is the area of the parallelogram made by the vectors where [math] |u| [/math] is the width and [math] |v|sin\theta[/math] is the height. Below is a reprezentation for the cross product.
Now let’s find the angle 😀
We can get the angle very easy from the basic formula:
There are two possible solutions between [math] 0 [/math] and [math] \pi [/math].
First solution is the value of [math] \theta [/math] itself, and second solution is [math] \pi- \theta [/math]. So be careful which angle you need in your application.
If you want the exterior angle of your vectors, take [math] 2\pi- \theta [/math]. This is useful to know in polygon triangulation when you need to find the angle based on vectors direction.
This decision can be done by checking the [math] z [/math] sign of the cross product.
Here is an implementation using C# :
private double VertexAngle(Vector v1, Vector v2) { // |a x b | = |a||b|sin(theta) var v3 = new double[3]; CrossProd(v1,v2,v3); //here we compute magnitude of cross Product // I know we could call Magnitude method but wanted to be more clear double mCrossProd= Math.Sqrt(v3[0]*v3[0] + v3[1]*v3[1] + v3[2]*v3[2]); var denom = Magnitude(v1)*Magnitude(v2); double angle = Math.Asin(mCrossProd/denom); if(v3[2]>0) angle = 2*Math.PI - angle; return angle; } private void CrossProd(Vector v1,Vector v2, double []res) { res[0] = v1.Y*v2.Z-v1.Z*v2.Y; res[1] = v1.Z*v2.X-v1.X*v2.Z; res[2] = v1.X*v2.Y-v1.Y*v2.X; } private double Magnitude(Vector v) {//Length return Math.Sqrt(v.X *v.X + v.Y *v.Y + v.Z*v.Z); }