Quaternions: A Real Pisser
I am writing a little space sim (for my personal game development education only) and I know Quaternions are diffinately the way to go...I''ve read just about every tutorial I can find on them, and I''ve written a class that can do all the mathmatical functions with Quaternions, but I have no idea how to actually use it all =). I''m tired of tutorials saying "...and so the unit vector can do blah blah here''s how to do blah blah but we''re not going to tell you this and that." This and that being how to actually rotate the quaternion, and get that rotation to rotate an object or camera. Can anyone tell me, or point me to a tutorial that will tell me "So, to rotate a quaternion using pitch, yaw, and roll..." and "Now use glLoadMatrix/translate+rotate on this..." I''d very much appreciate it. Thanks!
I''ll second that!
It seems we''re both doing very similar thing - i''m doing a kind of Elite clone, just to learn OpenGL and C ... and i''ve had much the same problems!
One suggestion ... try mailing Propuslor propulsor@web-discovery.net ... from the GLHorizon site ... worth checking out! He sent me some stuff, which i haven''t had time to look at yet ... thanks for that Propuslor!!!
Regards
Shag
It seems we''re both doing very similar thing - i''m doing a kind of Elite clone, just to learn OpenGL and C ... and i''ve had much the same problems!
One suggestion ... try mailing Propuslor propulsor@web-discovery.net ... from the GLHorizon site ... worth checking out! He sent me some stuff, which i haven''t had time to look at yet ... thanks for that Propuslor!!!
Regards
Shag
Once upona a time I was working on a programming site but the lack of interest in it caused me to abandon it. I do however have some info on quaternions there, including there use in a flight simulation type environment...
The main page is at
http://tannara.net/
the page I''m specifically referancing is here...
http://tannara.net/Graphics/Theory/3d_viewing_in_a_flight_simulations.htm
The main page is at
http://tannara.net/
the page I''m specifically referancing is here...
http://tannara.net/Graphics/Theory/3d_viewing_in_a_flight_simulations.htm
------------------------------Piggies, I need more piggies![pig][pig][pig][pig][pig][pig]------------------------------Do not invoke the wrath of the Irken elite. [flaming]
Assuming you have the quat-math functions and that they work:
what i do is the following:
I have 2 quats defined at all times. One holds the current orientation in the univers and the other holds what i call dOrientation (ie the difference in orientation from the last frame to the current).
Between frames i find out how much rotation is needed around the 3 axis (Euler). I create dOrientation from these 3 angles. Perform the multiplication: dOrientation*Orientation (in that specific order). Convert the dOrientation to AxisAngle and use glRotate to perform the AxisAngle-rotation.
Finally copy the values from dOrientation to Orientation.
Repeat each frame.
I had some problems because, first, i didnt use the dOrientation to hold the temporary rotation (still got that damn Gimbal-lock), and second i was multiplying in the wrong order (quat-multiplication is not commutative(called that in english ?)).
If you still have problems let me know and ill post some code.
Good luck
what i do is the following:
I have 2 quats defined at all times. One holds the current orientation in the univers and the other holds what i call dOrientation (ie the difference in orientation from the last frame to the current).
Between frames i find out how much rotation is needed around the 3 axis (Euler). I create dOrientation from these 3 angles. Perform the multiplication: dOrientation*Orientation (in that specific order). Convert the dOrientation to AxisAngle and use glRotate to perform the AxisAngle-rotation.
Finally copy the values from dOrientation to Orientation.
Repeat each frame.
I had some problems because, first, i didnt use the dOrientation to hold the temporary rotation (still got that damn Gimbal-lock), and second i was multiplying in the wrong order (quat-multiplication is not commutative(called that in english ?)).
If you still have problems let me know and ill post some code.
Good luck

Another thing which caused me some problems was finding the vector of translation from a quaternion. What i used is the following set of equations.
dirX = 2.0 * (x * z - w * y)
dirY = 2.0 * (y * z + w * x)
dirZ = 1.0 - 2.0 * (x * x + y * y);
Where w, x, y, z are the components of the Orientation quat.
Hope that helped
.
dirX = 2.0 * (x * z - w * y)
dirY = 2.0 * (y * z + w * x)
dirZ = 1.0 - 2.0 * (x * x + y * y);
Where w, x, y, z are the components of the Orientation quat.
Hope that helped

Darn, I have how no idea how to perform Quaternion-to-Euler conversion...I have Quaternion-to-Matrix Conversion, and thats what I''ve been using, but when I rotate the Quaternion, some really gnarly things happen to my skybox (the only object in the game right now). Things like two oppisite sides of the skybox coming closer together, and eventually going through eachother only to go back to normal, then back to almost touching eachother...Anyone else had this problem?
Here's my quat functions. feel free to use them even though they could use some optimization
.
Edited by - newdeal on July 17, 2001 1:50:04 PM

|
|
Edited by - newdeal on July 17, 2001 1:50:04 PM
Dave: quaternion to euler, like matrix to euler, doesn''t really work because you have to use inverse trig functions - because their domain is limited you aren''t guaranteed to get out the values that went in. It hasn''t mattered to me though, as I''ve yet to find a use for quaternion to euler conversion.
NewDeal: Similarly if you assume an object''s initial up vector (0,1,0), and left vector (1,0,0) then after being rotated by a quaternion:
up.x = 2 * (x*y - w*z)
up.y = 1 - 2 * (x*x + z*z)
up.z = 2 * (y*z + w*x)
left.x = 1 - 2 * (y*y + z*z)
left.y = 2 * (x*y + w*z)
left.z = 2 * (x*z - w*y)
You can derive those from standard quaternion to matrix conversion code.
NewDeal: Similarly if you assume an object''s initial up vector (0,1,0), and left vector (1,0,0) then after being rotated by a quaternion:
up.x = 2 * (x*y - w*z)
up.y = 1 - 2 * (x*x + z*z)
up.z = 2 * (y*z + w*x)
left.x = 1 - 2 * (y*y + z*z)
left.y = 2 * (x*y + w*z)
left.z = 2 * (x*z - w*y)
You can derive those from standard quaternion to matrix conversion code.
A couple things I forgot.
Like NewDeal suggested, try converting from quaternion to axis-angle, instead of quaternion to matrix. I find it much easier, and you''ll probably save some operations.
Ok now for how exactly you rotate stuff with quaternions. Each frame you decide how much you want your object to yaw, pitch, and roll based on user input. For example if the user moves the mouse 5 units left you could say that''s a yaw of 5 degrees. Anyway, you convert these yaw/pitch/roll angles (euler angles) to a quaternion. To actually rotate the object you just multiply this yaw/pitch/roll quaternion with the object''s current orientation.
quaternion temp = eulerAnglesToQuaternion(yaw, pitch, roll);
ship.orientation = temp * ship.orientation;
To display an object...
glTranslatef(ship.position);
vector axis;
float angle;
ship.orientation.quaternionToAxisAngle(&axis, ∠);
glRotatef(angle, axis.x, axis.y, axis.z);
//render the object here
How''s that?
For nice, smooth camera control with quaternions, look up articles on quaternion interpolation, also called slerp. There was also an interesting article in the Game Programming Gems book about a quaternion "shortest rotation arc" or something like that, I found it quite useful.
Like NewDeal suggested, try converting from quaternion to axis-angle, instead of quaternion to matrix. I find it much easier, and you''ll probably save some operations.
Ok now for how exactly you rotate stuff with quaternions. Each frame you decide how much you want your object to yaw, pitch, and roll based on user input. For example if the user moves the mouse 5 units left you could say that''s a yaw of 5 degrees. Anyway, you convert these yaw/pitch/roll angles (euler angles) to a quaternion. To actually rotate the object you just multiply this yaw/pitch/roll quaternion with the object''s current orientation.
quaternion temp = eulerAnglesToQuaternion(yaw, pitch, roll);
ship.orientation = temp * ship.orientation;
To display an object...
glTranslatef(ship.position);
vector axis;
float angle;
ship.orientation.quaternionToAxisAngle(&axis, ∠);
glRotatef(angle, axis.x, axis.y, axis.z);
//render the object here
How''s that?
For nice, smooth camera control with quaternions, look up articles on quaternion interpolation, also called slerp. There was also an interesting article in the Game Programming Gems book about a quaternion "shortest rotation arc" or something like that, I found it quite useful.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement