00001 #include <vecmath/_Euler4.h>
00002
00003 #include <iostream>
00004
00005 static const char *eulerDsc[] = {
00006
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
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
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);
00155 a[j] = sj*(cc + ss);
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