Convert from rotation matrix to quaternion
It is well known that rotation matrix can be represented by quaternion. This
page explains how to calculate the quaternions when the rotation matrix is
given.
Quaternion q=(q0,q1,q2,q3)
where |q|=1
Quaternion to rotation matrix.
Rotation matrix to quaternion. Following holds.
Therefore,
By solving this,
Now let's calculate the sign. q and -q represent same
rotation, thus,
Other sign will be as follows.
Another choice is to do as follows.
or
or
Source code: Convert rotation matrix to quaternion.
inline float
SIGN(
float
x) {
return
(x >= 0.0f) ? +1.0f : -1.0f;}
inline float
NORM(
float
a,
float
b,
float
c,
float
d) {
return
sqrt(a * a + b * b + c * c + d * d);}
q0 = ( r11 + r22 + r33 + 1.0f) / 4.0f;
q1 = ( r11 - r22 - r33 + 1.0f) / 4.0f;
q2 = (-r11 + r22 - r33 + 1.0f) / 4.0f;
q3 = (-r11 - r22 + r33 + 1.0f) / 4.0f;
if
(q0 <
0.0f) q0 = 0.0f;
if
(q1 <
0.0f) q1 = 0.0f;
if
(q2 <
0.0f) q2 = 0.0f;
if
(q3 <
0.0f) q3 = 0.0f;
q0 = sqrt(q0);
q1 = sqrt(q1);
q2 = sqrt(q2);
q3 = sqrt(q3);
if
(q0
>= q1 && q0 >= q2 && q0 >= q3) {
q0 *= +1.0f;
q1 *= SIGN(r32 - r23);
q2 *= SIGN(r13 - r31);
q3 *= SIGN(r21 - r12);
}
else
if
(q1 >= q0
&& q1 >= q2 && q1 >= q3) {
q0 *= SIGN(r32 - r23);
q1 *= +1.0f;
q2 *= SIGN(r21 + r12);
q3 *= SIGN(r13 + r31);
}
else
if
(q2 >= q0
&& q2 >= q1 && q2 >= q3) {
q0 *= SIGN(r13 - r31);
q1 *= SIGN(r21 + r12);
q2 *= +1.0f;
q3 *= SIGN(r32 + r23);
}
else
if
(q3 >= q0
&& q3 >= q1 && q3 >= q2) {
q0 *= SIGN(r21 - r12);
q1 *= SIGN(r31 + r13);
q2 *= SIGN(r32 + r23);
q3 *= +1.0f;
}
else
{
printf(
"coding
error\n"
);
}
r = NORM(q0, q1, q2, q3);
q0 /= r;
q1 /= r;
q2 /= r;
q3 /= r;
Back