00001
00002 #ifndef IG_STAT_COORDSYS_H
00003 #define IG_STAT_COORDSYS_H
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef IG_STAT_SMATRIX_H
00027 #include "stat_smatrix.h"
00028 #endif
00029
00030 #ifndef IG_STAT_QUATERNION_H
00031 #include "stat_quatern.h"
00032 #endif
00033
00034 #ifndef IG_STAT_SVECTOR_H
00035 #include "stat_svector.h"
00036 #endif
00037
00038
00039
00040 namespace CwMtx
00041 {
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 template <class T>
00057 CWTSSquareMatrix<3, T>
00058 smatFromEuler321Angles(T sclrAbout3,
00059 T sclrAbout2,
00060 T sclrAbout1)
00061 {
00062 CWTSSquareMatrix<3, T> smat;
00063
00064
00065
00066 T sin3 = sin(sclrAbout3);
00067 T sin2 = sin(sclrAbout2);
00068 T sin1 = sin(sclrAbout1);
00069
00070 T cos3 = cos(sclrAbout3);
00071 T cos2 = cos(sclrAbout2);
00072 T cos1 = cos(sclrAbout1);
00073
00074
00075 smat[0][0] = cos3*cos2;
00076 smat[0][1] = sin3*cos2;
00077 smat[0][2] = -sin2;
00078
00079
00080 smat[1][0] = -sin3*cos1 + cos3*sin2*sin1;
00081 smat[1][1] = cos3*cos1 + sin3*sin2*sin1;
00082 smat[1][2] = cos2*sin1;
00083
00084
00085 smat[2][0] = sin3*sin1 + cos3*sin2*cos1;
00086 smat[2][1] = -cos3*sin1 + sin3*sin2*cos1;
00087 smat[2][2] = cos2*cos1;
00088
00089 return smat;
00090 }
00091
00092
00093
00094
00095
00096
00097 template <class T>
00098 T
00099 euler321Angle3FromSmat(const CWTSSquareMatrix<3, T> &smat)
00100 {
00101 return atan2(smat[0][1], smat[0][0]);
00102 }
00103
00104
00105 template <class T>
00106 T
00107 euler321Angle2FromSmat(const CWTSSquareMatrix<3, T> &smat)
00108 {
00109 return asin(-smat[0][2]);
00110 }
00111
00112
00113 template <class T>
00114 T
00115 euler321Angle1FromSmat(const CWTSSquareMatrix<3, T> &smat)
00116 {
00117 return atan2(smat[1][2], smat[2][2]);
00118 }
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 template <class T>
00130 T
00131 euler321Angle3FromQtn(const CWTSQuaternion<T> &qtn)
00132 {
00133
00134 T qtn0 = qtn[0];
00135 T qtn1 = qtn[1];
00136 T qtn2 = qtn[2];
00137 T qtn3 = qtn[3];
00138
00139
00140
00141
00142 return atan2(2*(qtn0*qtn1 + qtn2*qtn3),
00143 2*(qtn0*qtn0 + qtn3*qtn3) - 1);
00144 }
00145
00146
00147 template <class T>
00148 T
00149 euler321Angle2FromQtn(const CWTSQuaternion<T> &qtn)
00150 {
00151 return asin(-2*(qtn[0]*qtn[2] - qtn[1]*qtn[3]));
00152 }
00153
00154
00155 template <class T>
00156 T
00157 euler321Angle1FromQtn(const CWTSQuaternion<T> &qtn)
00158 {
00159
00160 T qtn0 = qtn[0];
00161 T qtn1 = qtn[1];
00162 T qtn2 = qtn[2];
00163 T qtn3 = qtn[3];
00164
00165 return atan2(2*(qtn1*qtn2 + qtn0*qtn3),
00166 2*(qtn2*qtn2 + qtn3*qtn3) - 1);
00167 }
00168
00169
00170
00171
00172 template <class T>
00173 CWTSQuaternion<T>
00174 qtnFromEulerAxisAndAngle(const CWTSSpaceVector<T> &svecEulerAxis,
00175 const T &sclrEulerAngle)
00176 {
00177 return CWTSQuaternion<T>(1, svecEulerAxis, 0.5*sclrEulerAngle);
00178 }
00179
00180
00181 template <class T>
00182 CWTSSpaceVector<T>
00183 eulerAxisFromQtn(const CWTSQuaternion<T> &qtn)
00184 {
00185 T sclrTmp = sqrt(1 - qtn[3]*qtn[3]);
00186
00187 return CWTSSpaceVector<T>(qtn[0]/sclrTmp,
00188 qtn[1]/sclrTmp,
00189 qtn[2]/sclrTmp);
00190 }
00191
00192
00193 template <class T>
00194 T
00195 eulerAngleFromQtn(const CWTSQuaternion<T> &qtn)
00196 {
00197 return 2*acos(qtn[3]);
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 template <class T>
00210 CWTSQuaternion<T>
00211 qtnFromEuler321Angles(T sclrAbout3,
00212 T sclrAbout2,
00213 T sclrAbout1)
00214 {
00215 return
00216 CWTSQuaternion<T>(1, CWTSSpaceVector<T>(0, 0, 1), 0.5*sclrAbout3)
00217 *CWTSQuaternion<T>(1, CWTSSpaceVector<T>(0, 1, 0), 0.5*sclrAbout2)
00218 *CWTSQuaternion<T>(1, CWTSSpaceVector<T>(1, 0, 0), 0.5*sclrAbout1);
00219 }
00220
00221
00222
00223 template <class T>
00224 CWTSSquareMatrix<3, T>
00225 smatFromQtn(const CWTSQuaternion<T> &qtn)
00226 {
00227 CWTSSquareMatrix<3, T> smat;
00228
00229
00230 T qtn0 = qtn[0];
00231 T qtn1 = qtn[1];
00232 T qtn2 = qtn[2];
00233 T qtn3 = qtn[3];
00234
00235 smat[0][0] = 1 - 2*(qtn1*qtn1 + qtn2*qtn2);
00236 smat[0][1] = 2*(qtn0*qtn1 + qtn2*qtn3);
00237 smat[0][2] = 2*(qtn0*qtn2 - qtn1*qtn3);
00238
00239 smat[1][0] = 2*(qtn0*qtn1 - qtn2*qtn3);
00240 smat[1][1] = 1 - 2*(qtn0*qtn0 + qtn2*qtn2);
00241 smat[1][2] = 2*(qtn1*qtn2 + qtn0*qtn3);
00242
00243 smat[2][0] = 2*(qtn0*qtn2 + qtn1*qtn3);
00244 smat[2][1] = 2*(qtn1*qtn2 - qtn0*qtn3);
00245 smat[2][2] = 1 - 2*(qtn0*qtn0 + qtn1*qtn1);
00246
00247 return smat;
00248 }
00249
00250
00251
00252 template <class T>
00253 CWTSQuaternion<T>
00254 qtnFromSmat(const CWTSSquareMatrix<3, T> &smat)
00255 {
00256
00257 T sclrTmp = tr(smat);
00258 CWTSQuaternion<T> qtn;
00259
00260 if(sclrTmp > 0)
00261 {
00262
00263 sclrTmp = 0.5*sqrt(1 + sclrTmp);
00264 qtn[0] = 0.25*(smat[1][2] - smat[2][1])/sclrTmp;
00265 qtn[1] = 0.25*(smat[2][0] - smat[0][2])/sclrTmp;
00266 qtn[2] = 0.25*(smat[0][1] - smat[1][0])/sclrTmp;
00267 qtn[3] = sclrTmp;
00268 }
00269 else
00270 {
00271
00272
00273
00274
00275
00276 int i = 0;
00277 if (smat[1][1] > smat[0][0]) i = 1;
00278 if (smat[2][2] > smat[i][i]) i = 2;
00279
00280 switch (i)
00281 {
00282 case 0:
00283 sclrTmp = 0.5*sqrt(1 + smat[0][0] - smat[1][1] - smat[2][2]);
00284 qtn[0] = sclrTmp;
00285 qtn[1] = 0.25*(smat[0][1] + smat[1][0])/sclrTmp;
00286 qtn[2] = 0.25*(smat[0][2] + smat[2][0])/sclrTmp;
00287 qtn[3] = 0.25*(smat[1][2] - smat[2][1])/sclrTmp;
00288 break;
00289
00290 case 1:
00291 sclrTmp = 0.5*sqrt(1 - smat[0][0] + smat[1][1] - smat[2][2]);
00292 qtn[0] = 0.25*(smat[1][0] + smat[0][1])/sclrTmp;
00293 qtn[1] = sclrTmp;
00294 qtn[2] = 0.25*(smat[1][2] + smat[2][1])/sclrTmp;
00295 qtn[3] = 0.25*(smat[2][0] - smat[0][2])/sclrTmp;
00296 break;
00297
00298 case 2:
00299 sclrTmp = 0.5*sqrt(1 - smat[0][0] - smat[1][1] + smat[2][2]);
00300 qtn[0] = 0.25*(smat[2][0] + smat[0][2])/sclrTmp;
00301 qtn[1] = 0.25*(smat[2][1] + smat[1][2])/sclrTmp;
00302 qtn[2] = sclrTmp;
00303 qtn[3] = 0.25*(smat[0][1] - smat[1][0])/sclrTmp;
00304
00305 break;
00306 }
00307 }
00308
00309 return qtn;
00310 }
00311
00312
00313
00314 template <class T>
00315 CWTSVector<3, T>
00316 axisAngleFromQtn( const CWTSQuaternion<T> &qtn )
00317 {
00318 return eulerAxisFromQtn(qtn);
00319 }
00320
00321
00322
00323 template <class T>
00324 CWTSQuaternion<T>
00325 qtnFromAxisAndAngle(const CWTSVector<3, T> &vAxis,
00326 const T sAngle)
00327 {
00328 return qtnFromEulerAxisAndAngle(vAxis, sAngle);
00329 }
00330
00331 template <class T>
00332 CWTSSquareMatrix<3, T>
00333 changeOfBasis(CWTSSpaceVector< CWTSSpaceVector<T> >&from,
00334 CWTSSpaceVector< CWTSSpaceVector<T> >&to)
00335 {
00336 CWTSSquareMatrix<3, T> A;
00337
00338
00339
00340
00341
00342
00343
00344 enum { x , y , z };
00345
00346
00347
00348
00349
00350
00351
00352 A[0][0] = from[x]*to[x];
00353 A[0][1] = from[y]*to[x];
00354 A[0][2] = from[z]*to[x];
00355
00356 A[1][0] = from[x]*to[y];
00357 A[1][1] = from[y]*to[y];
00358 A[1][2] = from[z]*to[y];
00359
00360 A[2][0] = from[x]*to[z];
00361 A[2][1] = from[y]*to[z];
00362 A[2][2] = from[z]*to[z];
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 return A;
00373 }
00374
00375 }
00376
00377 #endif // IG_STAT_COORDSYS_H