Jump to content
  • Advertisement
Sign in to follow this  
josiah7

Getting A Vector To Look At Another Vector?

This topic is 4559 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This is driving me nuts! I hope someone here can please help me. I am using eular angles with two vectors. The z is the up axis (or pan), the x is the forward facing axis (roll), and the y is the tilt axis. I want to increment the pan and tilt (z and y) by degrees to point at the "camera" vector. I am kind of confused by all the (apparently) different methods, but I gather I need to first normalize each vector to a length of 1, then find the dot product. Then use the result with ACOS. This will give me the angle between the two vectors (right?) I have this so far; //=========================================================== vec_normalize(vec1,1); //normalize the vectors vec_normalize(vec2,1); angle =(acos(vec_dot(vec1,vec2))); //============================================================ Is this much correct? How can I convert this "angle" into degrees of pan and degrees of tilt I need to rotate the vector to get it to face the camera vector? Or am I way off with this approach? Thanks for any help with this!

Share this post


Link to post
Share on other sites
Advertisement
Take a look at these recent threads
http://www.gamedev.net/community/forums/topic.asp?topic_id=359774
http://www.gamedev.net/community/forums/topic.asp?topic_id=359332
which discusses the same problem.

I personally suggest you to avoid calculation of the yaw, pitch, and roll angles; IMHO using the standard look-at vector and the wanted look-at vector and computing a rotation matrix by using the pivot/angle pair would be a much better way.

Share this post


Link to post
Share on other sites
Why rotate around two vectors (which is the same as rotating around one vector).

so lets say you have vec1 and want it to rotate to vec2.

angle = acos( dot(vec1,vec2) );
rotVect = cross( vec1, vec2 );

and now rotate around the rotVector with the given angle.

Hope this helps.

Share this post


Link to post
Share on other sites
hi dude,
I have two approaches in mind.
First of all, this acos( dot_product() ) scheme returns the angle of two vectors *on the plane they form*, so it probably isn't what you want atm, since you want to derive two angles.

Now, two vectors are looking at each other if and only if one is v1=(x1,y1,z1) and the other is v2=(-x1,-y1,-z1), so why not directly set the vector you want to change, into the negative of the other one?

If you need the angles, however, the above won't help much. (though it'll do the job) I'd suggest you use the following formulas to switch into spherical coordinates and then reproject to cartesian after you got what you wanted...
In short, if you want vec1 to point to vec2, express vec2 in spherical coordinates. this way you can get its longitude 'phi'/latitude 'theta' with respect to its head. You obviously need to turn vec1 so that it would have longitude (-phi) and latitude (-theta). Given these angles you create the new vec1 in cartesian coordinates. I hope you see what I mean...
The equation for switching between cartesian-spherical are:

'mag' is the magnitude (length) of the vector

cartesian -> spherical
-----------------------
mag = sqrt( sqr(x)+sqr(y)+sqr(z) )
phi = atan(y/x)
theta = atan( z/sqrt(sqr(x)+sqr(y))

spherical -> cartesian
-----------------------
x = mag*cos(phi)*cos(theta)
y = mag*sin(phi)*cos(theta)
z = mag*sin(theta)

I suppose these will get the job done... :)

Share this post


Link to post
Share on other sites
Thanks everyone! I really appreciate the answers. All the different approaches
make it a little confusing. I should have stated at the onset that I know very
little about vector math. I thought that it would be simpiler to get these
two angles! Man this is frustrating! I will try to work out some of these ideas,

Thanks again for your time in helping me!

Share this post


Link to post
Share on other sites
Quote:
Original post by someusername
You obviously need to turn vec1 so that it would have longitude (-phi) and latitude (-theta)


oops, I made a mistake there, vec1's longitude should be phi+PI, not -phi.


Share this post


Link to post
Share on other sites
Quick question, I think mybe I have a problem with either my normalize function
or acos. When I use this on two vectors which are on a even plane and facing
each other directly, the angle returned is 110! as I make a flat orbit 360 on
this plane,(yaw or pan plane), the angle changes from high of 116 to a low of
58! and the high and low numbers dont seem to align with any axis. I would
expect 0 - 360.

Also if I use the SAME normalized vector like this;
//=============================================================
angle = acos(vec_dot(vec1,vec1));
//=============================================================

The angle returned is non zero! This dosent seem correct?
For instance, the angle I get for:
vec1 = 4,0,4;
vec2 = 4,0,4;
is 2.532!

This is what I am doing;
//=============================================================
vec_normalize(vec1,1);
vec_normalize(vec2,1);
angle = acos(vec_dot(vec1,vec2));
//=============================================================

Does this sound right?

Share this post


Link to post
Share on other sites
I haven't taken a look at your code, but...
... 58 sounds like an angle of 1 rad expressed in degrees.
... and 116 sounds like its double!

if you were expecting something like 360 (2pi rad), you probably forgot to multiply with PI somewhere...

Share this post


Link to post
Share on other sites
The problem is that you don't divide the dot product by the product of the vectors' lengths.

acos() expects arguments in the range {-1,...,1} (the range for cosine)
the dot product i.e. of (4.,0.,4.)dot(4.,0.,4.) is 32.
acos(32) won't work even if you're trying for a month. (actually it should return a complex number, but that's another story!)

anyway, the formula angle = acos( dot(v1,v2) ), works only for unit vectors and returns their *angle on the plane they form*, in the range (-PI/2,PI/2)
For arbitrary vectors you should divide the dot product by the product of their lengths. The actual formula for the dot product is

dot(v1,v2) = |v1|*|v2|*cos(angle)

, where |v| = sqrt(x*x +y*y + z*z), the length of vector v

Share this post


Link to post
Share on other sites
Thanks Someusername, I got it working. The angle provided is the angle
between the vectors tails at the world origin (0,0,0).

I am trying to create spherical billboarding with left hand eulers.

Heres where I am;
//=============================================================

vec_normalize(vec1,1);
vec_normalize(vec2,1);

angle = acos(vec_dot(vec1,vec2));

cross1.x = v1_temp.y*v2_temp.z - v2_temp.y*v1_temp.z;
cross1.y = v1_temp.z*v2_temp.x - v2_temp.z*v1_temp.x;
cross1.z = v1_temp.x*v2_temp.y - v2_temp.x*v1_temp.y;

//=============================================================

~I make the two vectors "unit vectors" with a length of 1.

~Use acos on the dot of these two vectors to get the angle between
them through the world center.

~Get the "left hand" cross product of the two unit vectors to
help determine rotation direction.

Now how can I use these numbers to make one object face another?
I can set an objects yaw and pitch directly, but how to determine
the angles I need from these results?

Thanks for any help on this problem!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!