[osg-users] How to scale rotations ?
Janusz
janusz at 3dcalc.pl
Fri Jul 25 12:13:32 PDT 2008
Dear all:
Appreciate any answer on the topic:
I am reading an orientation / rotation matrix info from a sensor, then
visualizing the rotation of an object on screen with OSG. Given the
matrix or the resulting quaternion I need to be able to scale the
rotations independently, i.e.
heading_scale*heading_angle, heading_scale=<0,1>
attitude_scale*attitude_angle
bank_scale*bank_angle
in order to be able to control them on its own or restrict the rotation
to one angle only.
I have written 2 functions. The first one converts a quaternion to the
Euler angles, the other one does the opposite. In between the calls to
the functions I am trying to scale the rotations or switch them on/off
as needed.
The results are not quite good, however, and I often get trapped in the
famous "gimbal lock" as probably expected. :-)
Q: Is there any other possibility to handle rotations on its own? Is
there a way to do that without running the conversion, scaling, then
converting back to quat ?
All I have is the rotation matrix.
Appreciate any answer/advice or pointing me in the right direction.
Best regards,
Janusz Goldasz
--
void getEulerFromQuat(osg::Quat q, double& heading, double& attitude,
double& bank)
{
double sqx = q.x()*q.x();
double sqy = q.y()*q.y();
double sqz = q.z()*q.z();
double t = q.x()*q.y() + q.z()*q.w();
if (t>0.49999)
{
heading = 2 * atan2(q.x(),q.w());
attitude = osg::PI_2;
bank = 0;
}
else if (t<-0.49999)
{
heading = -2 * atan2(q.x(),q.w());
attitude = - osg::PI_2;
bank = 0;
}
else
{
heading = atan2(2*q.y()*q.w()-2*q.x()*q.z() , 1 - 2*sqy - 2*sqz);
attitude = asin(2*t);
bank = atan2(2*q.x()*q.w()-2*q.y()*q.z() , 1 - 2*sqx - 2*sqz);
}
}
void getQuatFromEuler(double heading, double attitude, double bank,
osg::Quat& q)
{
double c1 = cos(heading/2);
double s1 = sin(heading/2);
double c2 = cos(attitude/2);
double s2 = sin(attitude/2);
double c3 = cos(bank/2);
double s3 = sin(bank/2);
double c1c2 = c1*c2;
double s1s2 = s1*s2;
double w =c1c2*c3 - s1s2*s3;
double x =c1c2*s3 + s1s2*c3;
double y =s1*c2*c3 + c1*s2*s3;
double z =c1*s2*c3 - s1*c2*s3;
q[0] = x; q[1] = y;
q[2] = z; q[3] = w;
}
More information about the osg-users
mailing list