PDA

View Full Version : Angle between two vectors



KurtCob
08-29-2000, 03:48 AM
Hello guys!!

I'm trying to find some information in the net about how to calculate the angle between two vectors, but it is coming really dificult, I know that here is not the best place to ask about this, but as the people are helping the others, how can I calculate the angle beetwen two points, and also between two lines...???

ahhhh....before I forget....does anyone know a good site in the net that show math like this stuff ???

Thank you for the moment

Best Regards

Kurt

Don't Disturb
08-29-2000, 04:13 AM
http://mathworld.wolfram.com/

inet
08-29-2000, 04:19 AM
hi, it's quite easy.

theta=acos((v1 DOT v2)/(|v1|*|v2|))

v1,v2: vector
DOT : dot product
|v1| : length of v1

KurtCob
08-29-2000, 05:34 AM
OK OK!!

But if it is a vector, (a point), how can I calculate it's length ?

I forgot everything of my math, how can I calculate the DOT product of the V1 and V2 ?

Thank you very much!

Bets regards

Kurt

Bob
08-29-2000, 06:16 AM
The length of the vector is sqtr(v.x*v.x + v.y*v.y + v.z*v.z) where v is your vector, and the dotproduct is (v1.x*v2.x)+(v1.y*v2.y)+(v1.z*v2.z) where v1 and v2 is your two vectors.

KurtCob
08-29-2000, 07:25 AM
Dear Bob,
I will try to implement something in this way.

Thank you very much huys!!!!
http://www.opengl.org/discussion_boards/ubb/smile.gif

Best Regards
Kurt

KurtCob
08-29-2000, 07:27 AM
Dear Bob,
I will try to implement something in this way.
Thank you very much guys!!!!

http://www.opengl.org/discussion_boards/ubb/smile.gif

Best Regards
Kurt

KurtCob
08-30-2000, 01:55 AM
Hello guys!!

I'm coming crazy... http://www.opengl.org/discussion_boards/ubb/mad.gif

Can someone see what I'm doing wrong with my code ?

At first of all, I'm using Windows SDK to develope my application.

#include <math.h>
#include ...

#define NC_PI 3.1415926

typedef struct {
float x,y;
}; VECTOR

float Get_Angle_Between_Points(int X1, int Y1, int X2, int Y2);

float dot_product(VECTOR _V1, VECTOR _V2);
float vector_length(VECTOR _V1);

float Get_Angle_Between_Points(int X1, int Y1, int X2, int Y2)
{
float vf_dot_product, vf_length_V1, vf_length_V2, angle;

VECTOR V1, V2;

V1.x = X1;
V1.y = Y1

V2.x = X2;
V2.y = Y2;

vf_dot_product = dot_product(V1, V2);
vf_length_V1 = vector_length(V1);
vf_length_V2 = vector_length(V2);

angle = acos((vf_dot_product/(vf_length_V1*vf_length_V2)));

// Convert the angle to degress
angle = angle * (180/NC_PI);

return angle;
}


float dot_product(VECTOR _V1, VECTOR _V2)
{
float dot_product;

dot_product = (_V1.x * _V2.x) + (_V1.y * _V2.y);

return dot_product;
}

float vector_length(VECTOR _V1)
{
float vector_length;

vector_length = sqrt(((_V1.x * _V1.x) + (_V1.y * _V1.y)));

return vector_length;
}

What is wrong ????

Thanks

Best Regards

Kurt

KurtCob
08-30-2000, 01:56 AM
Hello guys!!
I'm coming crazy... http://www.opengl.org/discussion_boards/ubb/mad.gif
Can someone see what I'm doing wrong with my code ?
At first of all, I'm using Windows SDK to develope my application.

#include <math.h>
#include ...

#define NC_PI 3.1415926
typedef struct {
float x,y;
}; VECTOR

float Get_Angle_Between_Points(int X1, int Y1, int X2, int Y2);
float dot_product(VECTOR _V1, VECTOR _V2);
float vector_length(VECTOR _V1);

float Get_Angle_Between_Points(int X1, int Y1, int X2, int Y2)
{
float vf_dot_product, vf_length_V1, vf_length_V2, angle;
VECTOR V1, V2;

V1.x = X1;
V1.y = Y1
V2.x = X2;
V2.y = Y2;

vf_dot_product = dot_product(V1, V2);
vf_length_V1 = vector_length(V1);
vf_length_V2 = vector_length(V2);
angle = acos((vf_dot_product/(vf_length_V1*vf_length_V2)));
// Convert the angle to degress
angle = angle * (180/NC_PI);
return angle;
}


float dot_product(VECTOR _V1, VECTOR _V2)
{
float dot_product;
dot_product = (_V1.x * _V2.x) + (_V1.y * _V2.y);
return dot_product;
}

float vector_length(VECTOR _V1)
{
float vector_length;
vector_length = sqrt(((_V1.x * _V1.x) + (_V1.y * _V1.y)));
return vector_length;
}

What is wrong ????
Thanks
Best Regards
Kurt

Bob
08-30-2000, 02:12 AM
What kind of error are you getting? A division by zero? Is the function returning crap? Get the same result all the time? A general protection fault? Anything?

KurtCob
08-30-2000, 02:17 AM
The fact is, that the returned value is always around 21 maximum 23, I really dont unterstand what is happening.

Thank's

Best regards

Kurt

skw|d
08-30-2000, 04:41 AM
First of all it is not considered a good practice to name variables the same as the function, though it should not cause any problems in your example.. This is because local variables usualy take up stack space or registers instead of the data segment, if you made those variables global you would get an error like 'redeclared as different kind of symbol.'

You don't even need to have a variable to get the value before you return:


return (_V1.x * _V2.x) + (_V1.y * _V2.y);
The compiler will probably use a register this way instead of the stack which is slower.

I like to use macros for this stuff:



#define dot_product(U,V) \
((U.x*V.x) + (U.y*V.y))


The reason why your code is screwing up is because you are passing a structure. You should instead pass by reference:


float vector_length( VECTOR *_V1 )
{
return sqrt((_V1->x + _V1->x) + (_V1->y * _V1->y));
}


/skw|d

dhiraj
08-30-2000, 11:16 AM
I haven't read through the posts completely, but here's an offhand suggestion, compute both the cos and sin products of the vectors and then take an atan2() of the sin and cos.
The sin and cos functions vary fast over certain intervals of their values, the atan2() function compensates for that.

Hope this helps,
Dhiraj.

The Wolf
08-30-2000, 12:23 PM
here's your problem:

you did:
angle = angle * (180/NC_PI);
return angle

you should be doing:
angle2 = angle * (180/NC_PI);
return angle2

i.e, use different variable
hope it works http://www.opengl.org/discussion_boards/ubb/smile.gif

Rob
08-30-2000, 01:29 PM
I don't see anything immediately wrong with your code. Are you certain that your input is correct?
No offense to The Wolf, but using a different variable shouldn't make any difference in this situation.

I just compiled and ran the code below, with the output indicated. The only change I made was to your struct definition (I think the change was insignificant). Looks fine to me.

#include <math.h>
#include <iostream.h>

#define NC_PI 3.1415926

struct VECTOR{
float x,y;
};

float Get_Angle_Between_Points(int X1, int Y1, int X2, int Y2);

float dot_product(VECTOR _V1, VECTOR _V2);
float vector_length(VECTOR _V1);

float Get_Angle_Between_Points(int X1, int Y1, int X2, int Y2)
{
float vf_dot_product, vf_length_V1, vf_length_V2, angle;

VECTOR V1, V2;

V1.x = X1;
V1.y = Y1;

V2.x = X2;
V2.y = Y2;

vf_dot_product = dot_product(V1, V2);
vf_length_V1 = vector_length(V1);
vf_length_V2 = vector_length(V2);

angle = acos((vf_dot_product/(vf_length_V1*vf_length_V2)));

// Convert the angle to degress
angle = angle * (180/NC_PI);

return angle;
}


float dot_product(VECTOR _V1, VECTOR _V2)
{
float dot_product;

dot_product = (_V1.x * _V2.x) + (_V1.y * _V2.y);

return dot_product;
}

float vector_length(VECTOR _V1)
{
float vector_length;

vector_length = sqrt(((_V1.x * _V1.x) + (_V1.y * _V1.y)));

return vector_length;
}

void main(){

cout << "angle: " << Get_Angle_Between_Points(0,1,1,0) << endl;

cout << "angle: " << Get_Angle_Between_Points(0,1,1,1) << endl;

cout << "angle: " << Get_Angle_Between_Points(0,1,8,1) << endl;

cout << "angle: " << Get_Angle_Between_Points(1,1,1,1) << endl;

}

output:
angle: 90
angle: 45
angle: 82.875
angle: -1.#IND

KurtCob
08-30-2000, 02:24 PM
Dear Rob,

Thank you very much for your reply, I will try to implement the code in my application.

Thanks

Kurt

KurtCob
08-31-2000, 01:08 AM
Hello guys!!

Could the problem be because I'm using gluUnProject, and using it's to calculate the angle ?

Thanks

Best Regards

Kurt

The Wolf
08-31-2000, 05:32 AM
you might wanna post the code with the openGL calls that your code makes.

Rob- I once had the same problem and believe it or not, changing variables made it work!! any idea why that happens?

KurtCob
08-31-2000, 07:14 AM
Ok Wolf!

I will try to put it in my code.

Thank you for the moment

Best regards

Kurt

Rob
08-31-2000, 09:26 AM
Wolf- I really don't know why it would make a difference. I don't consider myself a C/C++ expert at all. The best I can do is some wild, baseless speculation that maybe it's a compiler issue, or a C vs. C++ issue (I'm strictly C++ these days), or some wacky pointer issue.... Obviously, I'm clueless http://www.opengl.org/discussion_boards/ubb/smile.gif.

KurtCob
08-31-2000, 09:54 AM
Hello guys!

I changed the name of the variable, and I still have the problem.
http://www.opengl.org/discussion_boards/ubb/confused.gif
http://www.opengl.org/discussion_boards/ubb/confused.gif

I don't know what I have to do....

Thank you for the moment

Best regards

Kurt

Rob
08-31-2000, 11:03 AM
I suspect that you were right when you supposed that the problem was in your use of gluUnproject. Have you checked the values you are getting out of that to make sure they are correct?

KurtCob
08-31-2000, 12:13 PM
Ok...

I will check the result that comes from the gluUnProject.

Thanks

Best regards

Kurt

Inquisitor
09-01-2000, 04:41 AM
I checked it and it worked, but there were some things I think
you should change:

1.: #define NC_PI 3.1415926
No good, cause the compiler will create a double but you want a float. Add an 'f' to the number or, better, use
const float NC_PI 3.1415926f

2.: You pass your VECTOR structures to your functions by value. Bad. These functions are really small, inline them.
So better use this:
inline float dot_product(const VECTOR &_V1, const VECTOR &_V2)
{
return ((_V1.x * _V2.x) + (_V1.y * _V2.y));
}
inline float vector_length(const VECTOR &_V1)
{
return (float)sqrt((double)((_V1.x * _V1.x) + (_V1.y * _V1.y)));
}

3.: In the function Get_Angle_Between_Points you write
angle=acos((vf_dot_product/(vf_length_V1*vf_length_V2)));
I once had a compiler problem with something similar. I used some trig-function that wanted a double as parameter (just like acos). If I didn't explicitly cast the parameter to be a double it crashed. Since then I don't trust the compilers no more and always write
angle = (float)acos((double)(vf_dot_product/(vf_length_V1*vf_length_V2)));

4.: Instead of angle=angle*(180/NC_PI) better use angle*=(180.0f/NC_PI) or define another constant
const float NC_PI180=(180.0f/NC_PI);
and use that instead.
angle*=NC_PI180;

As I said at the beginning, none of these are normally a source for failures
as you described them, but especially #defines can often, depending on the
compiler, lead to some unwanted behaviour.

grady
09-03-2000, 05:12 AM
i dont feel like reading all those replies to see if this has already been said but have you taken into consideration the fact that two angles have the same acos(x). for instace acos(-.034202) =110 (thats what the computer will tell you) bit it also equals 250.

KurtCob
09-03-2000, 02:02 PM
Hello guys!!!!

I found the problem...now Im happy!!!

Thanks for all the help.

http://www.opengl.org/discussion_boards/ubb/smile.gif http://www.opengl.org/discussion_boards/ubb/smile.gif http://www.opengl.org/discussion_boards/ubb/smile.gif http://www.opengl.org/discussion_boards/ubb/smile.gif

Kurt

grady
09-04-2000, 02:05 PM
Well what was the problem? http://www.opengl.org/discussion_boards/ubb/smile.gif

KurtCob
09-04-2000, 02:19 PM
The input value, that I was sending to the function was wrong.

Thanks

Kurt