From ffedc87d0f92f8942169ce53ee8006f71f3688eb Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Mon, 11 Oct 2004 17:21:16 +0000 Subject: [PATCH] compute Euler angles from rotation matrix --- Common/Context.cpp | 130 ++++++++++++++------------------------------- 1 file changed, 41 insertions(+), 89 deletions(-) diff --git a/Common/Context.cpp b/Common/Context.cpp index 512aef0e3a..bbf955e848 100644 --- a/Common/Context.cpp +++ b/Common/Context.cpp @@ -1,4 +1,4 @@ -// $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 // @@ -29,102 +29,54 @@ #include "DefaultOptions.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) { - double x, y, z; - if(useTrackball) { build_rotmatrix(rot, quaternion); -#if defined(HAVE_FLTK) - // We should reconstruct the Euler angles from the rotation - // matrix. I'm too lazy to do it :-( - extern void set_r(int i, double val); - set_r(0, 0.); - set_r(1, 0.); - set_r(2, 0.); - /* - double x=0., y=0., z=0. - - y = asin(rot[2][0]) ; y = Pi - asin(rot[2][0]) ; // choix ??? - - 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); - set_r(1, y * 180./Pi); - set_r(2, z * 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); - set_r(1, r1 * 180./(Pi)); // lazyyyyyy - set_r(2, r2); - */ -#endif - + // get Euler angles from rotation matrix + r[1] = asin(rot[2][0]); // Calculate Y-axis angle + double C = cos(r[1]); + r[1] *= 180. / Pi; + if(fabs(C) > 0.005){ // Gimball lock? + double tmpx = rot[2][2] / C; // No, so get X-axis angle + double tmpy = -rot[2][1] / C; + r[0] = atan2(tmpy, tmpx) * 180. / Pi; + tmpx = rot[0][0] / C; // Get Z-axis angle + tmpy = -rot[1][0] / C; + r[2] = atan2(tmpy, tmpx) * 180. / Pi; + } + else{ // Gimball lock has occurred + r[0] = 0.; // Set X-axis angle to zero + double tmpx = rot[1][1]; // And calculate Z-axis angle + double tmpy = rot[0][1]; + r[2] = atan2(tmpy, tmpx) * 180. / Pi; + } + // return only positive angles in [0,360] + if(r[0] < 0.) r[0] += 360.; + if(r[1] < 0.) r[1] += 360.; + if(r[2] < 0.) r[2] += 360.; } else { - x = r[0] * Pi / 180.; - y = r[1] * Pi / 180.; - z = r[2] * Pi / 180.; - - rot[0][0] = cos(y) * cos(z); - rot[0][1] = sin(x) * sin(y) * cos(z) + cos(x) * sin(z); - rot[0][2] = -cos(x) * sin(y) * cos(z) + sin(x) * sin(z); - rot[0][3] = 0.0; - - rot[1][0] = -cos(y) * sin(z); - rot[1][1] = -sin(x) * sin(y) * sin(z) + cos(x) * cos(z); - rot[1][2] = cos(x) * sin(y) * sin(z) + sin(x) * cos(z); - rot[1][3] = 0.0; - - rot[2][0] = sin(y); - rot[2][1] = -sin(x) * cos(y); - rot[2][2] = cos(x) * cos(y); - rot[2][3] = 0.0; - - rot[3][0] = 0.0; - rot[3][1] = 0.0; - rot[3][2] = 0.0; - rot[3][3] = 1.0; + double x = r[0] * Pi / 180.; + double y = r[1] * Pi / 180.; + double z = r[2] * Pi / 180.; + double A = cos(x); + double B = sin(x); + double C = cos(y); + double D = sin(y); + double E = cos(z); + double F = sin(z); + double AD = A * D; + double BD = B * D; + 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][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[3][0] = 0.; rot[3][1] = 0.; rot[3][2] = 0.; rot[3][3] = 1.; + + // get the quaternion from the Euler angles + // todo } - } void Context_T::addQuaternion(float p1x, float p1y, float p2x, float p2y) -- GitLab