_Euler4.cc

Go to the documentation of this file.
00001 #include <vecmath/_Euler4.h>
00002 
00003 #include <iostream>
00004 
00005 static const char *eulerDsc[] = {
00006     // matching order!
00007     "EulOrdXYZs",
00008     "EulOrdZYXr",
00009 
00010     "EulOrdXYXs",
00011     "EulOrdXYXr",
00012 
00013     "EulOrdXZYs",
00014     "EulOrdYZXr",
00015 
00016     "EulOrdXZXs",
00017     "EulOrdXZXr",
00018 
00019     "EulOrdYZXs",
00020     "EulOrdXZYr",
00021 
00022     "EulOrdYZYs",
00023     "EulOrdYZYr",
00024 
00025     "EulOrdYXZs",
00026     "EulOrdZXYr",
00027 
00028     "EulOrdYXYs",
00029     "EulOrdYXYr",
00030 
00031     "EulOrdZXYs",
00032     "EulOrdYXZr",
00033 
00034     "EulOrdZXZs",
00035     "EulOrdZXZr",
00036 
00037     "EulOrdZYXs",
00038     "EulOrdXYZr",
00039 
00040     "EulOrdZYZs",
00041     "EulOrdZYZr"
00042 };
00043 
00044 /* using the power of C */
00045 
00046 #define SET_BY_MATRIX(m) do { \
00047     int i, j, k, h, n, s, f;\
00048     order = _order;\
00049     EulGetOrd(order, i, j, k, h, n, s, f);\
00050     if (s == EulRepYes) {\
00051         double sy = sqrt(Math::sqr(m(i,j)) + Math::sqr(m(i,k)));\
00052         if (sy > 16 * FLT_EPSILON) {\
00053             x = atan2(m(i,j), m(i,k));\
00054             y = atan2(sy, m(i,i));\
00055             z = atan2(m(j,i), -m(k,i));\
00056         } else {\
00057             x = atan2(-m(j,k), m(j,j));\
00058             y = atan2(sy, m(i,i));\
00059             z = 0;\
00060         }\
00061     } else {\
00062         double cy = sqrt(m(i,i)*m(i,i) + m(j,i)*m(j,i));\
00063         if (cy > 16 * FLT_EPSILON) {\
00064             x = atan2(m(k,j), m(k,k));\
00065             y = atan2(-m(k,i), cy);\
00066             z = atan2(m(j,i), m(i,i));\
00067         } else {\
00068             x = atan2(-m(j,k), m(j,j));\
00069             y = atan2(-m(k,i), cy);\
00070             z = 0;\
00071         }\
00072     }\
00073     if (n == EulParOdd) {\
00074         x = -x; y = -y; z = -z;\
00075     }\
00076     if (f == EulFrmR)\
00077         Math::swap(x, z);\
00078     } while(0)
00079 
00080 #define COMMON_CODE \
00081     int i, j, k, h, n, s, f;\
00082     EulGetOrd(order,i,j,k,h,n,s,f);\
00083     double ti = x;\
00084     double tj = y;\
00085     double th = z;\
00086     if (f == EulFrmR)\
00087         Math::swap(ti, th);\
00088     if (n == EulParOdd) {\
00089         ti = -ti; tj = -tj; th = -th;\
00090     }\
00091     double ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
00092 
00093 
00094 #define GET_BY_MATRIX(m) do {\
00095     COMMON_CODE\
00096     ci = cos(ti); cj = cos(tj); ch = cos(th);\
00097     si = sin(ti); sj = sin(tj); sh = sin(th);\
00098     cc = ci * ch; cs = ci * sh; sc = si * ch; ss = si * sh;\
00099     if (s==EulRepYes) {\
00100         m(i,i) =  cj;      m(i,j) =  sj * si;      m(i,k) =  sj * ci;\
00101         m(j,i) =  sj * sh; m(j,j) = -cj * ss + cc; m(j,k) = -cj * cs - sc;\
00102         m(k,i) = -sj * ch; m(k,j) =  cj * sc + cs; m(k,k) =  cj * cc - ss;\
00103     } else {\
00104         m(i,i) =  cj * ch; m(i,j) = sj *sc - cs;   m(i,k) = sj * cc + ss;\
00105         m(j,i) =  cj * sh; m(j,j) = sj *ss + cc;   m(j,k) = sj * cs - sc;\
00106         m(k,i) = -sj;      m(k,j) = cj *si;        m(k,k) = cj * ci;\
00107     }\
00108     } while(0)
00109 
00110 // typeless
00111 #define CLEAN_MATRIX4(m) do {\
00112     m(W,X) = m(W,Y) = m(W,Z) = m(X,W) = m(Y,W) = m(Z,W) = 0.0;\
00113     m(W,W) = 1.0;\
00114     } while(0)
00115 
00116 
00117 template <class Type>
00118 void _Euler4<Type>::get(_Matrix4<double>& m) const
00119 {
00120     GET_BY_MATRIX(m);
00121     CLEAN_MATRIX4(m);
00122 }
00123 
00124 template <class Type>
00125 void _Euler4<Type>::get(_Matrix4<float>& m) const
00126 {
00127     GET_BY_MATRIX(m);
00128     CLEAN_MATRIX4(m);
00129 }
00130 
00131 template <class Type>
00132 void _Euler4<Type>::get(_Matrix3<double>& m) const
00133 {
00134     GET_BY_MATRIX(m);
00135 }
00136 
00137 template <class Type>
00138 void _Euler4<Type>::get(_Matrix3<float>& m) const
00139 {
00140     GET_BY_MATRIX(m);
00141 }
00142 
00143 template <class Type>
00144 void _Euler4<Type>::get(_Quat4<double>& q) const
00145 {
00146     COMMON_CODE
00147     ti *= 0.5; tj *= 0.5; th *= 0.5;
00148     ci = cos(ti);  cj = cos(tj);  ch = cos(th);
00149     si = sin(ti);  sj = sin(tj);  sh = sin(th);
00150     cc = ci*ch; cs = ci*sh; sc = si*ch; ss = si*sh;
00151 
00152     double a[3];
00153     if (s==EulRepYes) {
00154         a[i] = cj*(cs + sc);    /* Could speed up with */
00155         a[j] = sj*(cc + ss);    /* trig identities. */
00156         a[k] = sj*(cs - sc);
00157         q.w = cj*(cc - ss);
00158     } else {
00159         a[i] = cj*sc - sj*cs;
00160         a[j] = cj*ss + sj*cc;
00161         a[k] = cj*cs - sj*sc;
00162         q.w = cj*cc + sj*ss;
00163     }
00164     if (n == EulParOdd)
00165         a[j] = -a[j];
00166 
00167     q.x = a[X];
00168     q.y = a[Y];
00169     q.z = a[Z];
00170 }
00171 
00172 
00173 template <class Type>
00174 void _Euler4<Type>::set(const _Matrix4<double>& m, order_t _order)
00175 {
00176     SET_BY_MATRIX(m);
00177 }
00178 
00179 template <class Type>
00180 void _Euler4<Type>::set(const _Matrix4<float>& m, order_t _order)
00181 {
00182     SET_BY_MATRIX(m);
00183 }
00184 
00185 template <class Type>
00186 void _Euler4<Type>::set(const _Matrix3<double>& m, order_t _order)
00187 {
00188     SET_BY_MATRIX(m);
00189 }
00190 
00191 template <class Type>
00192 void _Euler4<Type>::set(const _Matrix3<float>& m, order_t _order)
00193 {
00194     SET_BY_MATRIX(m);
00195 }
00196 
00197 template <class Type> std::ostream& operator <<(std::ostream& os, const _Euler4<Type>* t)
00198 {
00199     return os << *t;
00200 }
00201 
00202 template <class Type> std::ostream& operator <<(std::ostream& os, const _Euler4<Type>& t)
00203 {
00204     os << t.EulOrdXYZr << " UUU" << std::endl;
00205     return os << "( Phi(Roll):" << t.x << ", Theta(Pitch): " << t.y <<
00206         ", Psi(Yaw): " << t.z << ", " << eulerDsc[t.order] << " )";
00207 }
00208 
00209 template class _Euler4<float>;
00210 template class _Euler4<double>;
00211 
00212 template std::ostream& operator <<(std::ostream&, const _Euler4<double>&);
00213 template std::ostream& operator <<(std::ostream&, const _Euler4<double>*);
00214 template std::ostream& operator <<(std::ostream&, const _Euler4<float>&);
00215 template std::ostream& operator <<(std::ostream&, const _Euler4<float>*);
00216 

Generated on Thu Sep 29 13:39:44 2005 for vecmath by  doxygen 1.4.4