Answered by:
Angle between vectors
Question

Hi !
Can you provide me with asimple code (in C) that calculates the angles between two vectoors provided that the angle ranges from [pi,pi] ?!
Two formulas available are :
A*B=A.Btan(Teta)
A.B = ABcos(Teta)
I think I need to use the first one using atan2() function to have symmetric(+&) results. Any idea?
Thursday, August 27, 2009 2:44 PM
Answers

That is exactly right. Using A.B = ABcos(t) will provide angles from pi/2 > +pi/2.
I think I need to use the first one using atan2() function to have symmetric(+&) results. Any idea?
This works out (in 2D) as:
double angle = atan2(vec2.y, vec2.x)  atan2(vec1.y, vec1.x);
If you want this in 3D, you probably will need to just use the cross product, and compute that axis separately. Otherwise, I'd recommend going with quaternions.
Reed Copsey, Jr.  http://reedcopsey.com Marked as answer by yade Thursday, August 27, 2009 3:45 PM
Thursday, August 27, 2009 3:21 PM 
I think I need to use the first one using atan2() function to have symmetric(+&) results. Any idea?
That is exactly right. Using A.B = ABcos(t) will provide angles from pi/2 > +pi/2.
http://msdn.microsoft.com/enus/library/bztkwykh.aspx
Giovanni
You're absolutely right. Sorry about that. using A.B = ... will give you angles between 0 > pi.
yade 
You'll want to use atan2 to get the results you want, as I posted before. I just misspoke in the first section there.
Reed Copsey, Jr.  http://reedcopsey.com Marked as answer by yade Thursday, August 27, 2009 3:46 PM
Thursday, August 27, 2009 3:32 PM
All replies

That is exactly right. Using A.B = ABcos(t) will provide angles from pi/2 > +pi/2.
I think I need to use the first one using atan2() function to have symmetric(+&) results. Any idea?
This works out (in 2D) as:
double angle = atan2(vec2.y, vec2.x)  atan2(vec1.y, vec1.x);
If you want this in 3D, you probably will need to just use the cross product, and compute that axis separately. Otherwise, I'd recommend going with quaternions.
Reed Copsey, Jr.  http://reedcopsey.com Marked as answer by yade Thursday, August 27, 2009 3:45 PM
Thursday, August 27, 2009 3:21 PM 
That is exactly right. Using A.B = ABcos(t) will provide angles from pi/2 > +pi/2.
I think I need to use the first one using atan2() function to have symmetric(+&) results. Any idea?
I'm not sure. The acos function (inverse of cos ) returns the value in range [0, pi], as can be read here:
http://msdn.microsoft.com/enus/library/bztkwykh.aspx
Giovanni
 Edited by Giovanni Dicanio Thursday, August 27, 2009 3:32 PM typo
Thursday, August 27, 2009 3:28 PM 
I would suggest you to use the dot product formula, which involves the cosine of the angle between the two vectors.
You can do a little bit of math, and use acos() function (i.e. the inverse of cosine) to get the value of the angle theta, expressing it in terms of dot product between two given vectors and their modules, i.e.:
theta = acos( a . b / (a b) )
where '.' represents the dot product between two vectors.
Note that the acos() function returns an angle in radians in range [0, pi].
This is a sample compilable C code I wrote to show that (I did not test it extensively, but it should work):
#include <stdio.h> #include <math.h> // Given 3D vector 'v', returns its module (i.e. length) double Vec3_Module(const double * v) { return sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); } // Given two 3D vectors, returns the dot product between them double Vec3_Dot(const double * a, const double * b) { return (a[0]*b[0] + a[1]*b[1] + a[2]*b[2]); } // Given a pair of 3D vectors, returns the angle between them. // Angle is expressed in radians, in range [0, PI] double Vec3_Angle(const double * a, const double * b) { // // From dot product definition: // // a . b = a b cos(theta) // // ==> cos(theta) = a . b / (a b) // // ==> theta = acos( a . b / (a b) ) // return acos( Vec3_Dot(a, b) / (Vec3_Module(a) * Vec3_Module(b)) ); } // Test Vec3_Angle function void Test() { double a[] = {1, 2, 1}; double b[] = {0, 1, 3}; printf("a = [%g, %g, %g]\n", a[0], a[1], a[2]); printf("b = [%g, %g, %g]\n", b[0], b[1], b[2]); printf("Angle = %g\n", Vec3_Angle(a, b)); } int main() { Test(); return 0; }
HTH,
Giovanni
Thursday, August 27, 2009 3:32 PM 
I think I need to use the first one using atan2() function to have symmetric(+&) results. Any idea?
That is exactly right. Using A.B = ABcos(t) will provide angles from pi/2 > +pi/2.
http://msdn.microsoft.com/enus/library/bztkwykh.aspx
Giovanni
You're absolutely right. Sorry about that. using A.B = ... will give you angles between 0 > pi.
yade 
You'll want to use atan2 to get the results you want, as I posted before. I just misspoke in the first section there.
Reed Copsey, Jr.  http://reedcopsey.com Marked as answer by yade Thursday, August 27, 2009 3:46 PM
Thursday, August 27, 2009 3:32 PM 
Thanks Guys !
I think atan2 is the best way to do it. I am gonna check it, let u know if it was not correct !
Many Thanks!Thursday, August 27, 2009 3:46 PM