 Allegro.cc Forums » Programming Questions » Angle Between Two Vectors?

 This thread is locked; no one can reply to it.  Angle Between Two Vectors?
 Mr. Big Member #6,196 September 2005 How do I get the angle between two vectors with the same origin?The two ways I know (using 'acos' and 'atan2') return some confusing results.How do I convert those results to the range of 0 - 2 pi (or 0 - 360 degrees, or whatever)?Thanks.
Thomas Harte
Member #33
April 2000 Are you working out the individual angles of the lines from their origin, then trying to do some arithmetic on those values? If so then that would explain your issues. An easier solution is the dot product.

For two vectors, A and B:

A . B = |A||B|cos(angle between A and B)

|A| is the length of A, so you can find that with Pythagoras.

So, if you have A = (ax, ay) and B = (bx, by) then:

angle between = acos( ((ax * bx) + (ay * by)) / (sqrt(ax*ax + ay*ay) * sqrt(bx*bx + by*by))

If you use the acos from math.h then the result will be in the range -pi/2 to pi/2. Be careful though — it'll always give you the smallest angle between the vectors, so if two vectors start with the same orientation and then one stays still and the other rotates then the angle between them will go up from 0 to pi/2, then down again from pi/2 to -pi/2, then up from -pi/2 to 0.

If you want a full -pi to pi then you need to do a further check to decide if the two vectors are both pointing "the same way". Imagine one vector is lying exactly on the x-axis pointing right. Then you want to decide whether the other is pointing right or left.

You can do that using the dot product too — check whether ((ax * bx) + (ay * by)) is negative or positive and add or subtract pi from your result depending on its sign and which angle you want to measure.

 1 float get_angle_between_in_radians(float ax, float ay, float bx, float by) 2 { 3 float dotproduct, lengtha, lengthb, result; 4 5 dotproduct = (ax * bx) + (ay * by); 6 lengtha = sqrt(ax * ax + ay * ay); 7 lengthb = sqrt(bx * bx + by * by); 8 9 result = acos( dotproduct / (lengtha * lengthb) ); 10 11 if(dotproduct < 0) 12 { 13 if(result > 0) 14 result += M_PI; 15 else 16 result -= M_PI; 17 } 18 return result; 19 }

There's lots on the web about the dot product, and it's something that's very easy to understand the properties of, even if it takes you a while to really see why it all works...

 Mr. Big Member #6,196 September 2005 Oh! Should have thought about it myself!I'm stupid.Thanks, Thomas. [EDIT]Your code doesn't actually work because 'atan' returns values in range of 0 - pi, but thanks for the idea with the dot product and angle signs.This works like it should: ```float angle_between_vectors(VECTOR o, VECTOR a, VECTOR b) { VECTOR t1 = VECTOR_DIFF(a, o), t2 = VECTOR_DIFF(b, o); float result; result = (atan2(t1.y, t1.x) - atan2(t2.y, t2.x)) * 180.0 * M_1_PI; if(result < 0) result += 360.0; return result; } ```
Paul Rowan
Member #8,612
May 2007 Hi,

I'm not that mathematical, but I have a full code list for finding the angle between 2 points, don't know if this is the same as vectors but I'll post it here just in case it is for you to use if you want it 1 #include 2 #include 3 4 #define PI 3.1415926535 5 6 #define WHITE makecol(255,255,255) 7 8 //define function prototype 9 double get_angle(int x1,int y1,int x2, int y2); 10 11 int main() 12 { 13 allegro_init(); 14 15 set_gfx_mode(GFX_SAFE, 640, 480, 0, 0); 16 17 install_keyboard(); 18 19 //variables for calculating angle 20 double ang1; 21 double ang2; 22 23 //first x,y co-ords 24 int x1=150; 25 int y1=150; 26 27 //second x,y co-ords 28 int x2=100; 29 int y2=100; 30 31 ang1=get_angle(x1,y1,x2,y2); 32 33 //Add or subtract 180 degrees to ang1 to get the angle for ang2 34 if(ang1<=180) ang2=ang1+180; 35 else ang2=ang1-180; 36 37 textprintf(screen,font,10,10,WHITE,"Point 1 = %d , %d (x: horizontal [+ = right], y: vertical [+ = up])",x1,y1); 38 textprintf(screen,font,10,25,WHITE,"Point 2 = %d , %d",x2,y2); 39 40 if(ang1==-1) 41 { 42 textprintf(screen,font,10,40,WHITE,"%s","The Points are the same!"); 43 } 44 else 45 { 46 textprintf(screen,font,10,40,WHITE,"The Angle from Point 2 to Point 1 is %f degrees",ang1); 47 textprintf(screen,font,10,55,WHITE,"The Angle from Point 1 to Point 2 is %f degrees",ang2); 48 } 49 50 while(! key[KEY_ESC]); 51 allegro_exit(); 52 return 0; 53 } 54 55 END_OF_MAIN(); 56 57 58 double get_angle(int x1,int y1,int x2, int y2) 59 { 60 double opp; 61 double adj; 62 double ang1; 63 64 //calculate vector differences 65 opp=y1-y2; 66 adj=x1-x2; 67 68 if(x1==x2 && y1==y2) return(-1); 69 70 //trig function to calculate angle 71 if(adj==0) // to catch vertical co-ord to prevent division by 0 72 { 73 if(opp>=0) 74 { 75 return(0); 76 } 77 else 78 { 79 return(180); 80 } 81 } 82 else 83 { 84 ang1=(atan(opp/adj))*180/PI; 85 //the angle calculated will range from +90 degrees to -90 degrees 86 //so the angle needs to be adjusted if point x1 is less or greater then x2 87 if(x1>=x2) 88 { 89 ang1=90-ang1; 90 } 91 else 92 { 93 ang1=270-ang1; 94 } 95 } 96 return(ang1); 97 }

 Go to: Allegro Development Installation, Setup & Configuration Allegro.cc Comments Off-Topic Ordeals The Depot Game Design & Concepts Programming Questions Recent Threads