Page 1 of 1
Gimbal lock and quaternion rotation issue
Posted: Wed Dec 26, 2012 9:19 am
by Squirrel
Hi all,
I'am new to Irrlicht and i'm trying to solve a node rotation issue for about a week.
I searched through the forum and found explanations about the "gimbal lock" problem and a way to avoid it using quaternions.
so, i wrote the following function which works fine except when a node is previously rotated -90.0 degrees on the Y axis (then, Z axis rotations are locked).
I think I misunderstood something about the gimbal lock and/or the use of quaternions to avoid it... or maybe I just did something wrong with my code.
Code: Select all
void QRotate(ISceneNode* node, float angle, vector3df axis) // Quaternion Rotation
{
quaternion quat_rot, quat_old;
quat_rot.fromAngleAxis(angle*DEGTORAD, axis);
quat_old.set(node->getRotation()*DEGTORAD);
quat_rot*=quat_old;
quat_rot.normalize();
node->setRotation (quat_rot.getMatrix().getRotationDegrees());
}
Any help will be much appreciate.
Thanks in advance.
Re: Gimbal lock and quaternion rotation issue
Posted: Wed Dec 26, 2012 4:05 pm
by smso
Re: Gimbal lock and quaternion rotation issue
Posted: Wed Dec 26, 2012 4:07 pm
by Abraxas)
Code: Select all
core::vector3df heading(0.0f, 1.0f, 0.0f);
matrix.rotateVect(heading);
// rotate node to face the point:
core::quaternion q;
q.rotationFromTo(heading, dir);
core::vector3df eulerRadians;
q.toEuler(eulerRadians);
obj->plane->node->setRotation(eulerRadians * core::RADTODEG);
Re: Gimbal lock and quaternion rotation issue
Posted: Wed Dec 26, 2012 5:34 pm
by Squirrel
Thank you both!
@smso
I had a matrix function to do objetct's relative rotations but none so far that worked using world space, so this will be very useful.
Beyond the usefulness of this one, I really want to understand what's the mistake(s) I made using quartenions.
To multiply two quaternions is supposed to do rotations effectively if I'am not wrong?
I modified my code to use absoluteTransformation functions without success.
Any idea about what I did wrong? I'll continue to search by my side anyway...
@Abraxas)
Your snippet is very interesting too and as I guess it will be very useful in some situations it points me to admit that I've got some difficulties to vizualize rotations using vectors.
e.g. in your code I don't know how to determine clearly the "heading" and "dir" vectors if I have to apply rotations to an already rotaded node.
I have to work on this too.
Thanks again
Re: Gimbal lock and quaternion rotation issue
Posted: Wed Dec 26, 2012 6:02 pm
by Abraxas)
heading is your "default" rotation. Every direction vector will be relative to this. So a rotation of (0,0,0) corresponds to a heading of (0,1,0).
dir is your desired facing direction. So if you want to face sideways, you want a heading of (1,0,0) or (0,0,1) or even (1,0,1) or (-1,0,-1) or whatnot. You should normalize this vector after deciding on your heading.
The quaternion:
http://en.wikipedia.org/wiki/Quaternion
http://en.wikipedia.org/wiki/Gimbal_lock
This can be explained intuitively by the fact that a quaternion describes a rotation in one single move ("please turn radians around the axis driven by vector "), while the Euler angles are made of three successive rotations.
---
So therefore the quaternion is a representation of the rotation that would move from heading to direction. You use the toEuler() vector format to do node->setRotation(eulerrotaion * radianstodegrees).
Re: Gimbal lock and quaternion rotation issue
Posted: Thu Dec 27, 2012 5:22 am
by smso
I changed 1 line in your code and it should work now:
Code: Select all
void testRotateInLocalSpace(scene::ISceneNode* node, f32 degs, const core::vector3df& axis)
{
core::quaternion q;
q.fromAngleAxis(degs*core::DEGTORAD, axis);
core::quaternion q0;
q0.set(node->getRotation() * core::DEGTORAD);
q = q * q0;
//q *= q0; //FIXME not working, maybe a bug?
q.normalize();
node->setRotation(q.getMatrix().getRotationDegrees());
}
Regards,
smso
Re: Gimbal lock and quaternion rotation issue
Posted: Thu Dec 27, 2012 10:12 am
by Squirrel
Thank you for your answers!
@ Abraxas)
Code: Select all
So a rotation of (0,0,0) corresponds to a heading of (0,1,0)
This was the missing information!.... where I could expect to go if I hadn't any starting reference?
It's more clear now.
About the wiki pages, i read them many times but even if if think i understood the practical concept of quaternions, explanations are far above my math skills.
Anyway, I just realize i was wrong to always thinking using object's relative rotations, i guess using absolute references is a better way to use quaternions... i've got to make some tests.
@ smso
I tested the modified code and thought first the problem was fixed as the Z axis rotation worked but i noticed (maybe because of the fact that the multiplication of quaternions is not commutative) that the changes lead to swap from absolute to relative rotation. So, now it's the relative X axis which is locked.
Nice try anyway.
Anyways, using your explanations and study your snippets will help me to go further.
Thanks
Re: Gimbal lock and quaternion rotation issue
Posted: Fri Dec 28, 2012 4:34 am
by Mikhail9
Quats can be really hard to visualize. Look at a variety of different tutorials on the web until you start to get a picture of how they work. Don't give up too easily!
Re: Gimbal lock and quaternion rotation issue
Posted: Fri Dec 28, 2012 4:05 pm
by Squirrel
Just in case of someone else would make the same mistake that I made :
If I understood correctly the math explanations I just read about rotations using quaternions, I think that I made a mistake doing a direct multiplication of the quaternions.
The right way seems to be to use a quaternion to build a rotation matrix then to multiply it with a matrix created from the vector.
This is exactly what smso wrote in the rotateNodeInWorldSpace function
http://irrlicht.sourceforge.net/forum/v ... =9&t=47924
Thanks again for your help.
Re: Gimbal lock and quaternion rotation issue
Posted: Fri Dec 28, 2012 5:40 pm
by Abraxas)
Quats are really easy to understand.
Step 1: Create a plane in 3-d space.
Step 2: rotate the plane.
That's all a quat tells you.