3D rotation based on 2 vectors...

Started by
13 comments, last by Glaiel_Gamer 18 years, 1 month ago
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?
Advertisement
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.
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)
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. :)
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.
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.
Author Freeworld3Dhttp://www.freeworld3d.org
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)
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.
[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
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)

This topic is closed to new replies.

Advertisement