Suppose I have gimbal angles pitch, yaw and roll. Could any one tell me how to convert from gimbal angles to quaternion?
Any suggestion will be highly appreciated.
Suppose I have gimbal angles pitch, yaw and roll. Could any one tell me how to convert from gimbal angles to quaternion?
Any suggestion will be highly appreciated.
From the wildmagic libary (Matrix3.h):
First go from Euler angles to a rotation matrix:
template <typename Real>
void Matrix3<Real>::MakeEulerXYZ (Real xAngle, Real yAngle, Real zAngle)
{
Real cs, sn;
cs = Math<Real>::Cos(xAngle);
sn = Math<Real>::Sin(xAngle);
Matrix3 xMat(
(Real)1, (Real)0, (Real)0,
(Real)0, cs, -sn,
(Real)0, sn, cs);
cs = Math<Real>::Cos(yAngle);
sn = Math<Real>::Sin(yAngle);
Matrix3 yMat(
cs, (Real)0, sn,
(Real)0, (Real)1, (Real)0,
-sn, (Real)0, cs);
cs = Math<Real>::Cos(zAngle);
sn = Math<Real>::Sin(zAngle);
Matrix3 zMat(
cs, -sn, (Real)0,
sn, cs, (Real)0,
(Real)0, (Real)0, (Real)1);
*this = xMat*(yMat*zMat);
}
And then from a rotation matrix to a quaternion.
There are some details... This is using a left handed coord sys, and the euler angle are X first, Y, then Z. I don't think either of these conform to the standard flight system, but this hopefully will give you a start.//----------------------------------------------------------------------------
void HQuaternion::FromRotationMatrix (const HMatrix& rot)
{
// Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
// article "HQuaternion Calculus and Fast Animation".
const int next[3] = { 1, 2, 0 };
float trace = rot(0,0) + rot(1,1) + rot(2,2);
float root;
if (trace > (float)0)
{
// |w| > 1/2, may as well choose w > 1/2
root = sqrtf(trace + 1.0f); // 2w
mTuple[0] = 0.5f*root;
root = 0.5f/root; // 1/(4w)
mTuple[1] = (rot(2,1) - rot(1,2))*root;
mTuple[2] = (rot(0,2) - rot(2,0))*root;
mTuple[3] = (rot(1,0) - rot(0,1))*root;
}
else
{
// |w| <= 1/2
int i = 0;
if (rot(1,1) > rot(0,0))
{
i = 1;
}
if (rot(2,2) > rot(i,i))
{
i = 2;
}
int j = next[i];
int k = next[j];
root = sqrtf(rot(i,i) - rot(j,j) - rot(k,k) + (float)1);
float* quat[3] = { &mTuple[1], &mTuple[2], &mTuple[3] };
*quat[i] = 0.5f*root;
root = 0.5f/root;
mTuple[0] = (rot(k,j) - rot(j,k))*root;
*quat[j] = (rot(j,i) + rot(i,j))*root;
*quat[k] = (rot(k,i) + rot(i,k))*root;
}
}
The code is at:
wildmagic
Every rotation can be converted to quaternion singularly and then combined.
qx = [sin(pitch*0.5f), 0, 0, cos(pitch*0.5f)];
qy = [0, sin(yaw*0.5f), 0, cos(yaw*0.5f)];
qz = [0, 0, sin(roll*0.5f), cos(roll*0.5f)];
and now you can combine the quaternion in the order you prefer.
qFinal = qx*qy*qz;
I leave the simplification as exercise.
~ ~ I tell you, realtime 3D is made of blood, sweat and screams! ~ ~
Nice, hadn't thought about that. Skip the rotation matrix altogether...Originally Posted by Rosario Leonardi
Thanks a lot to both of you!
Be warned though, quats are just one parametrization of possible rotations out of many. You can get gimbal lock with quats too.
Can you post an example of that?Originally Posted by ugluk
As far as I understand, each parametrization has it's own attributes / flaws. Quaternions don't suffer from gimbal lock, while euler coordinates do.Originally Posted by Wiki
Not true.
visualizing quaternions
You get a gimbal lock example on page 53. The idea is that you can combine quats representing rotations much like you can matrices. You can convert rotation matrices into quats. So what if you combine quats representing rotations around x, y, z axes? The results must be identical as when combining rotation matrices and so you get gimbal lock.
Because you are using quaternion in a wrong way.
If you use Euler to compute matrix and then matrix to compute quaternion (or Euler to compute quaternion) you still have gimbal lock but is not a problem of quaternion is the same Euler problem.
Quaternion are used to represent an orientation, given ANY orientation you are still able to rotate around all axis.
~ ~ I tell you, realtime 3D is made of blood, sweat and screams! ~ ~
If you are using C++, take a look at the quaternion example at:
http://clanlib.org/wiki/Examples#3D_examples
(You will need to download the complete source ( http://clanlib.org/wiki/Download ) for the example )
It shows how quaternion vs euler angles work.
Since clanlib's has a BSD style license, you should be able to extract the code (if required).