Skip to content
Snippets Groups Projects
Commit ffedc87d authored by Christophe Geuzaine's avatar Christophe Geuzaine
Browse files

compute Euler angles from rotation matrix
parent 542667e0
No related branches found
No related tags found
No related merge requests found
// $Id: Context.cpp,v 1.50 2004-02-07 01:40:17 geuzaine Exp $ // $Id: Context.cpp,v 1.51 2004-10-11 17:21:16 geuzaine Exp $
// //
// Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
// //
...@@ -29,102 +29,54 @@ ...@@ -29,102 +29,54 @@
#include "DefaultOptions.h" #include "DefaultOptions.h"
#include "Trackball.h" #include "Trackball.h"
/*
3 successive rotations along x, y and z:
c(y)c(z) s(x)s(y)c(z)+c(x)s(z) -c(x)s(y)c(z)+s(x)s(z)
t[][] = -c(y)s(z) -s(x)s(y)s(z)+c(x)c(z) c(x)s(y)s(z)+s(x)c(z)
s(y) -s(x)c(y) c(x)c(y)
get the position angles:
y = asin(t31)
Pi - asin(t31)
si y != +- Pi/2 :
x = atan(-t32/t33) si t33 cos y > 0
atan(-t32/t33)+Pi si t33 cos y < 0
z = atan(-t21/t11) si t11 cos y > 0
atan(-t21/t11)+Pi si t11 cos y < 0
*/
void Context_T::buildRotmatrix(void) void Context_T::buildRotmatrix(void)
{ {
double x, y, z;
if(useTrackball) { if(useTrackball) {
build_rotmatrix(rot, quaternion); build_rotmatrix(rot, quaternion);
#if defined(HAVE_FLTK) // get Euler angles from rotation matrix
// We should reconstruct the Euler angles from the rotation r[1] = asin(rot[2][0]); // Calculate Y-axis angle
// matrix. I'm too lazy to do it :-( double C = cos(r[1]);
extern void set_r(int i, double val); r[1] *= 180. / Pi;
set_r(0, 0.); if(fabs(C) > 0.005){ // Gimball lock?
set_r(1, 0.); double tmpx = rot[2][2] / C; // No, so get X-axis angle
set_r(2, 0.); double tmpy = -rot[2][1] / C;
/* r[0] = atan2(tmpy, tmpx) * 180. / Pi;
double x=0., y=0., z=0. tmpx = rot[0][0] / C; // Get Z-axis angle
tmpy = -rot[1][0] / C;
y = asin(rot[2][0]) ; y = Pi - asin(rot[2][0]) ; // choix ??? r[2] = atan2(tmpy, tmpx) * 180. / Pi;
if(fabs(y) != Pi/2.){
if(rot[2][2]*cos(y) > 0.) x = atan2(-rot[2][1],rot[2][2]);
else x = atan2(-rot[2][1],rot[2][2]) + Pi;
if(rot[0][0]*cos(y) > 0.) z = atan2(-rot[1][0],rot[0][0]);
else z = atan2(-rot[1][0],rot[0][0]) + Pi;
} }
set_r(0, x * 180./Pi); else{ // Gimball lock has occurred
set_r(1, y * 180./Pi); r[0] = 0.; // Set X-axis angle to zero
set_r(2, z * 180./Pi); double tmpx = rot[1][1]; // And calculate Z-axis angle
*/ double tmpy = rot[0][1];
/* r[2] = atan2(tmpy, tmpx) * 180. / Pi;
double r0, r1, r2;
r1 = atan2(-rot[0][2],sqrt(rot[1][2]*rot[1][2] + rot[2][2]*rot[2][2]));
double c = cos(r1);
if(c != 0.0){
r0 = atan2(rot[1][2]/c,rot[2][2]/c) ;
r2 = atan2(-rot[1][0]/c,rot[0][0]/c) ;
r0 *= 180./(Pi);
r2 *= 180./(Pi);
} }
set_r(0, r0); // return only positive angles in [0,360]
set_r(1, r1 * 180./(Pi)); // lazyyyyyy if(r[0] < 0.) r[0] += 360.;
set_r(2, r2); if(r[1] < 0.) r[1] += 360.;
*/ if(r[2] < 0.) r[2] += 360.;
#endif
} }
else { else {
x = r[0] * Pi / 180.; double x = r[0] * Pi / 180.;
y = r[1] * Pi / 180.; double y = r[1] * Pi / 180.;
z = r[2] * Pi / 180.; double z = r[2] * Pi / 180.;
double A = cos(x);
rot[0][0] = cos(y) * cos(z); double B = sin(x);
rot[0][1] = sin(x) * sin(y) * cos(z) + cos(x) * sin(z); double C = cos(y);
rot[0][2] = -cos(x) * sin(y) * cos(z) + sin(x) * sin(z); double D = sin(y);
rot[0][3] = 0.0; double E = cos(z);
double F = sin(z);
rot[1][0] = -cos(y) * sin(z); double AD = A * D;
rot[1][1] = -sin(x) * sin(y) * sin(z) + cos(x) * cos(z); double BD = B * D;
rot[1][2] = cos(x) * sin(y) * sin(z) + sin(x) * cos(z); rot[0][0] = C*E; rot[0][1] = BD*E+A*F; rot[0][2] =-AD*E+B*F; rot[0][3] = 0.;
rot[1][3] = 0.0; rot[1][0] =-C*F; rot[1][1] =-BD*F+A*E; rot[1][2] = AD*F+B*E; rot[1][3] = 0.;
rot[2][0] = D; rot[2][1] =-B*C; rot[2][2] = A*C; rot[2][3] = 0.;
rot[2][0] = sin(y); rot[3][0] = 0.; rot[3][1] = 0.; rot[3][2] = 0.; rot[3][3] = 1.;
rot[2][1] = -sin(x) * cos(y);
rot[2][2] = cos(x) * cos(y); // get the quaternion from the Euler angles
rot[2][3] = 0.0; // todo
rot[3][0] = 0.0;
rot[3][1] = 0.0;
rot[3][2] = 0.0;
rot[3][3] = 1.0;
} }
} }
void Context_T::addQuaternion(float p1x, float p1y, float p2x, float p2y) void Context_T::addQuaternion(float p1x, float p1y, float p2x, float p2y)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment