Sign in to follow this  
Glaiel_Gamer

3D rotation based on 2 vectors...

Recommended Posts

Ok i have a 3D shape, and a forwards vector and an upwards vector. How can I make it so that the shape is facing the forwards vector? Do i need more than one call to glRotatef? I can get it to face the forwards vector, but it does barrel rolls when i try to move it so how do i incorporate the upwards vector into it?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
http://en.wikipedia.org/wiki/Quaternion

This basically allows you to use one vector as the vector you want to rotate around. Or you can draw all your vectors out by hand and do some trigonometry on them to produce the rotation you want.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
i know how to make a vector rotate about another vector, but that's not what i need. I need to know how to use GLROTATE to make one shape face a vector (and have the top of it face the up vector)

Share this post


Link to post
Share on other sites
You would need to do more than one glRotatef call, essentially one for each axis.
Unless, that is, you are using Quaternions, like the first AP said.

Edit: With Quaternions, it's a little different. :)

Share this post


Link to post
Share on other sites
No you don't *need* multiple rotate calls. glRotate provides arbitrary axis-angle rotation, iirc. If you know the vector along which the shape is currently facing, and the vector along which you want it to face, you can compute the axis of rotation via the cross product of those two vectors, use the dot product to compute the angle of rotation, and feed the axis and angle to glRotate.

This will perform shortest arc rotation, but that might not look the way you want, in which case you may need to perform more complex operations to get the object to "bank" or rotate about its roll axis, et cetera.

Share this post


Link to post
Share on other sites
This is how you would do it: (assuming forward and up are unit vectors)

Vector3 cross = crossProduct(forward, up);
float radians = acos(dot(forward, up));
float degrees = radians*360.0f / (2*3.14159f); // converts radians to degrees


Now when rendering your model you call

glRotatef(degrees, cross.x, cross.y, cross.z);


It can be done without quaternions.

Share this post


Link to post
Share on other sites
everything you gus said i already know! The thing i need is the fact that when i rotate that way, if i'm not facing the right way the shape spins around it's axis (ie the top is not right)

that's why i made such a big deal about the up vector.


(PS i dont know anything all about these "quaternions" i'm only in algebra 2)

Share this post


Link to post
Share on other sites
Quote:
Original post by oconnellseanm
This is how you would do it: (assuming forward and up are unit vectors)

Vector3 cross = crossProduct(forward, up);
float radians = acos(dot(forward, up));
float degrees = radians*360.0f / (2*3.14159f); // converts radians to degrees


Now when rendering your model you call

glRotatef(degrees, cross.x, cross.y, cross.z);


It can be done without quaternions.


no, that didnt work at all. For one thing, the angle between the forwards and up vectors is always 90°.

Forwards and up represent the rotation I want the object (currently facing 0,0,1 (down the Z axis)) to rotate to.

Share this post


Link to post
Share on other sites
[edit - forgot to preformat the text but you get the idea...]

If you want to maintain a specific up axis then you're correct the shortest arc rotation won't be correct. If you want to use glRotate then you'll need to use 2 calls. A better way might be to generate the desired matrix directly and use glMultMatrix. In dirty pseudocode this would look something like:

side = forward x up
if (|side| == 0)
side = your choice of side vector, say [1, 0, 0]
up = side x forward

Then build a rotation matrix with columns [side, up, -forward] (note that forward needs to be negated for the OpenGL convention). This is basically the way gluLookAt works.

HTH

Share this post


Link to post
Share on other sites
thanks a lot doofus (lol)

So it seems kinda easy, the matrix i'm using right now is:

[txx+c, txy - sz, txz + sy]
[txy + sz, tyy + c, tyz - sx]
[txz - sy, tyz + sx, tzz + c ]

t = 1-cos angle
c = cos angle
s = sin angle

or the matrix is something like that.. so is that how i would build the matrix? Or am i using the completely wrong one and should i start over (this is used to rotate a specific vector about an axis for my camera class)

Share this post


Link to post
Share on other sites
Quote:
Original post by anist
couldn't you just use gluLookAt to generate the matrix using the two vectors, then apply that matrix to your object? Best way I can think of.


doesnt gluLookAt just change the camera? This is what i'm pretty much trying to do (use gluLookAt for an object) so how do i get the matrix from it?

Share this post


Link to post
Share on other sites
That's what I gave in my post. gluLookAt will modify the matrix stack itself. To accomplish what gluLookAt does, use the steps in my post to calculate the matrix.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this