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