00001
00002 #ifndef __JBXL_CPP_QUATERNION_H_
00003 #define __JBXL_CPP_QUATERNION_H_
00004
00012 #include "Matrix++.h"
00013 #include "Vector.h"
00014
00015
00016
00017 namespace jbxl {
00018
00019
00021
00022
00023
00024 template <typename T> class DllExport Quaternion;
00025
00026
00027 template <typename T> Vector<T> Quaternion2ExtEulerXYZ(Quaternion<T> qut, Vector<T>* vct=NULL);
00028 template <typename T> Vector<T> Quaternion2ExtEulerZYX(Quaternion<T> qut, Vector<T>* vct=NULL);
00029 template <typename T> Vector<T> Quaternion2ExtEulerXZY(Quaternion<T> qut, Vector<T>* vct=NULL);
00030 template <typename T> Vector<T> Quaternion2ExtEulerYZX(Quaternion<T> qut, Vector<T>* vct=NULL);
00031 template <typename T> Vector<T> Quaternion2ExtEulerYXZ(Quaternion<T> qut, Vector<T>* vct=NULL);
00032 template <typename T> Vector<T> Quaternion2ExtEulerZXY(Quaternion<T> qut, Vector<T>* vct=NULL);
00033
00034
00035
00037
00045 template <typename T=double> class DllExport Quaternion
00046 {
00047 public:
00048 T s;
00049 T x;
00050 T y;
00051 T z;
00052
00053 T n;
00054 T c;
00055
00056 public:
00057 Quaternion(void) { init();}
00058 Quaternion(T S, T X, T Y, T Z, T N=(T)0.0, T C=(T)1.0) { set(S, X, Y, Z, N, C);}
00059 Quaternion(T S, Vector<T> v) { setRotation(S, v);}
00060 virtual ~Quaternion(void) {}
00061
00062 T norm(void) { n = (T)sqrt(s*s+x*x+y*y+z*z); return n;}
00063 void normalize(void);
00064
00065 void set(T S, T X, T Y, T Z, T N=(T)0.0, T C=(T)1.0);
00066 void init(T C=(T)1.0) { s=n=(T)1.0; x=y=z=(T)0.0; c=C;}
00067
00068 Vector<T> getVector() { Vector<T> v(x, y, z, (T)0.0, c); return v;}
00069 T getScalar() { return s;}
00070 T getAngle() { return (T)(2.0*acos(s));}
00071 T getMathAngle() { T t=(T)(2.0*acos(s)); if(t>(T)PI)t-=(T)PI2; return t;}
00072
00073 Matrix<T> getRotMatrix();
00074
00075 void setRotation(T e, Vector<T> v);
00076 void setRotation(T e, T X, T Y, T Z, T N=(T)0.0) { Vector<T> v(X, Y, Z, N); setRotation(e, v);}
00077
00078 void setRotate(T e, Vector<T> v) { setRotation(e, v);}
00079 void setRotate(T e, T X, T Y, T Z, T N=(T)0.0) { Vector<T> v(X, Y, Z, N); setRotation(e, v);}
00080
00081
00082 void setExtEulerXYZ(Vector<T> e);
00083 void setExtEulerZYX(Vector<T> e);
00084 void setExtEulerXZY(Vector<T> e);
00085 void setExtEulerYZX(Vector<T> e);
00086 void setExtEulerYXZ(Vector<T> e);
00087 void setExtEulerZXY(Vector<T> e);
00088
00089 Vector<T> getExtEulerXYZ(Vector<T>* vt=NULL) { return Quaternion2ExtEulerXYZ<T>(*this, vt);}
00090 Vector<T> getExtEulerZYX(Vector<T>* vt=NULL) { return Quaternion2ExtEulerZYX<T>(*this, vt);}
00091 Vector<T> getExtEulerXZY(Vector<T>* vt=NULL) { return Quaternion2ExtEulerXZY<T>(*this, vt);}
00092 Vector<T> getExtEulerYZX(Vector<T>* vt=NULL) { return Quaternion2ExtEulerYZX<T>(*this, vt);}
00093 Vector<T> getExtEulerYXZ(Vector<T>* vt=NULL) { return Quaternion2ExtEulerYXZ<T>(*this, vt);}
00094 Vector<T> getExtEulerZXY(Vector<T>* vt=NULL) { return Quaternion2ExtEulerZXY<T>(*this, vt);}
00095
00096 Vector<T> execRotation(Vector<T> v);
00097 Vector<T> execInvRotation(Vector<T> v);
00098 Vector<T> execRotate(Vector<T> v) { return execRotation(v);}
00099 Vector<T> execInvRotate(Vector<T> v) { return execInvRotation(v);}
00100 };
00101
00102
00103
00105
00106
00107 template <typename T> inline bool operator == (const Quaternion<T> q1, const Quaternion<T> q2)
00108 { return (q1.s==q2.s && q1.x==q2.x && q1.y==q2.y && q1.z==q2.z); }
00109
00110
00111 template <typename T> inline bool operator != (const Quaternion<T> q1, const Quaternion<T> q2)
00112 { return (q1.s!=q2.s || q1.x!=q2.x || q1.y!=q2.y || q1.z!=q2.z); }
00113
00114
00116 template <typename T> inline Quaternion<T> operator ~ (const Quaternion<T> a)
00117 { return Quaternion<T>(a.s, -a.x, -a.y, -a.z, a.n, a.c); }
00118
00119
00120
00121 template <typename T> inline Quaternion<T> operator - (const Quaternion<T> a)
00122 { return Quaternion<T>(-a.s, -a.x, -a.y, -a.z, a.n, a.c); }
00123
00124
00125 template <typename T> inline Quaternion<T> operator + (const Quaternion<T> a, const Quaternion<T> b)
00126 { return Quaternion<T>(a.s+b.s, a.x+b.x, a.y+b.y, a.z+b.z, (T)0.0, Min(a.c, b.c)); }
00127
00128
00129 template <typename T> inline Quaternion<T> operator - (const Quaternion<T> a, const Quaternion<T> b)
00130 { return Quaternion<T>(a.s-b.s, a.x-b.x, a.y-b.y, a.z-b.z, (T)0.0, Min(a.c, b.c)); }
00131
00132
00133 template <typename T, typename R> inline Quaternion<T> operator * (const R d, const Quaternion<T> a)
00134 { return Quaternion<T>((T)d*a.s, (T)d*a.x, (T)d*a.y, (T)d*a.z, (T)d*a.n, a.c); }
00135
00136
00137 template <typename T, typename R> inline Quaternion<T> operator * (const Quaternion<T> a, const R d)
00138 { return Quaternion<T>(a.s*(T)d, a.x*(T)d, a.y*(T)d, a.z*(T)d, a.n*(T)d, a.c); }
00139
00140
00141 template <typename T, typename R> inline Quaternion<T> operator / (const Quaternion<T> a, const R d)
00142 { return Quaternion<T>(a.s/(T)d, a.x/(T)d, a.y/(T)d, a.z/(T)d, a.n/(T)d, a.c); }
00143
00144
00148 template <typename T> inline Quaternion<T> operator * (const Quaternion<T> a, const Quaternion<T> b)
00149 {
00150 Quaternion<T> quat;
00151 if (a.c<(T)0.0 || b.c<(T)0.0) quat.init(-(T)1.0);
00152 else quat.set(a.s*b.s-a.x*b.x-a.y*b.y-a.z*b.z, a.s*b.x+a.x*b.s+a.y*b.z-a.z*b.y,
00153 a.s*b.y+a.y*b.s+a.z*b.x-a.x*b.z, a.s*b.z+a.z*b.s+a.x*b.y-a.y*b.x, (T)1.0, Min(a.c, b.c));
00154 return quat;
00155 }
00156
00157
00158
00159 template <typename T> inline Quaternion<T> operator * (const Quaternion<T> q, const Vector<T> v)
00160 {
00161 Quaternion<T> quat;
00162 if (q.c<(T)0.0 || v.c<(T)0.0) quat.init(-(T)1.0);
00163 else quat.set(-q.x*v.x-q.y*v.y-q.z*v.z, q.s*v.x+q.y*v.z-q.z*v.y,
00164 q.s*v.y+q.z*v.x-q.x*v.z, q.s*v.z+q.x*v.y-q.y*v.x, v.n, Min(q.c, v.c));
00165 return quat;
00166 }
00167
00168
00169
00170 template <typename T> inline Quaternion<T> operator * (const Vector<T> v, const Quaternion<T> q)
00171 {
00172 Quaternion<T> quat;
00173 if (q.c<(T)0.0 || v.c<(T)0.0) quat.init(-(T)1.0);
00174 else quat.set(-v.x*q.x-v.y*q.y-v.z*q.z, v.x*q.s+v.y*q.z-v.z*q.y,
00175 v.y*q.s+v.z*q.x-v.x*q.z, v.z*q.s+v.x*q.y-v.y*q.x, (T)v.n, (T)Min(v.c, q.c));
00176 return quat;
00177 }
00178
00179
00180
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 #define Quaternion2RotMatrix(q) (q).getRotMatrix()
00235
00236
00237
00238 template <typename T> inline Quaternion<T> ExtEulerXYZ2Quaternion(Vector<T> e) { Quaternion<T> q; q.setExtEulerXYZ(e); return q;}
00239 template <typename T> inline Quaternion<T> ExtEulerZYX2Quaternion(Vector<T> e) { Quaternion<T> q; q.setExtEulerZYX(e); return q;}
00240 template <typename T> inline Quaternion<T> ExtEulerXZY2Quaternion(Vector<T> e) { Quaternion<T> q; q.setExtEulerXZY(e); return q;}
00241 template <typename T> inline Quaternion<T> ExtEulerYZX2Quaternion(Vector<T> e) { Quaternion<T> q; q.setExtEulerYZX(e); return q;}
00242 template <typename T> inline Quaternion<T> ExtEulerYXZ2Quaternion(Vector<T> e) { Quaternion<T> q; q.setExtEulerYXZ(e); return q;}
00243 template <typename T> inline Quaternion<T> ExtEulerZXY2Quaternion(Vector<T> e) { Quaternion<T> q; q.setExtEulerZXY(e); return q;}
00244
00245
00246
00247
00249
00250
00251
00252
00253
00254
00255
00256 #define VectorRotate(v, q) VectorRotation((v),(q))
00257 #define VectorInvRotate(v, q) VectorInvRotation((v), (q))
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00274
00275
00276
00283 template <typename T=double> class DllExport AffineTrans
00284 {
00285 public:
00286 Matrix<T> matrix;
00287
00288 Vector<T> shift;
00289 Vector<T> scale;
00290 Quaternion<T> rotate;
00291
00292 bool isInverse;
00293
00294 public:
00295 AffineTrans(void) { setup();}
00296 virtual ~AffineTrans(void) {}
00297
00298 void initComponents(void) { initScale(); initRotate(); initShift(); isInverse = false;}
00299
00300 void setup(void){ initComponents(); matrix = Matrix<T>(2, 4, 4);}
00301 void set(Vector<T> s, Quaternion<T> q, Vector<T> t, bool inv=false) { scale=s; shift=t, rotate=q; isInverse=inv; computeMatrix(true);}
00302 void free(void) { initComponents(); matrix.free();}
00303 void clear(void){ initComponents(); matrix.clear();}
00304 void dup(AffineTrans a);
00305
00306 void computeMatrix(bool with_scale=true);
00307 void computeComponents(void);
00308
00309 void initShift (void) { shift.init();}
00310 void initScale (void) { scale.set((T)1.0, (T)1.0, (T)1.0);}
00311 void initRotate(void) { rotate.init();}
00312
00313 void setShift (T x, T y, T z) { shift.set(x, y, z);}
00314 void setScale (T x, T y, T z) { scale.set(x, y, z);}
00315 void setRotate(T s, T x, T y, T z) { rotate.setRotation(s, x, y, z);}
00316
00317 void addShift (T x, T y, T z) { shift.x += x; shift.y += y; shift.z += z;}
00318 void addScale (T x, T y, T z) { scale.x *= x; scale.y *= y; scale.z *= z;}
00319 void addRotate(T s, T x, T y, T z) { Quaternion<T> q(s, x, y, z); rotate = q*rotate;}
00320
00321 Vector<T> getShift (void) { return shift;}
00322 Vector<T> getScale (void) { return scale;}
00323 Quaternion<T> getRotate(void) { return rotate;}
00324 Matrix<T> getMatrix(void) { return matrix;}
00325 Matrix<T> getRotMatrix(void);
00326 AffineTrans<T> getInvAffine(void);
00327
00328 bool isSetComponents(void) { if(isSetShift() || isSetScale() || isSetRotate()) return true; else return false;}
00329 bool isSetShift(void) { return (shift !=Vector<T>());}
00330 bool isSetScale(void) { return (scale !=Vector<T>((T)1.0, (T)1.0, (T)1.0));}
00331 bool isSetRotate(void) { return (rotate!=Quaternion<T>());}
00332 bool isNormal(void) { if(scale.x>=JBXL_EPS && scale.y>=JBXL_EPS && scale.z>=JBXL_EPS) return true; else return false;}
00333
00334
00335 Vector<T> execMatrixTrans(Vector<T> v);
00336
00337 Vector<T> execTrans(Vector<T> v) { if(!isInverse) return execShift(execRotate(execScale(v)));
00338 else return execScale(execRotate(execShift(v)));}
00339 Vector<T> execInvTrans(Vector<T> v) { if(!isInverse) return execInvScale(execInvRotate(execInvShift(v)));
00340 else return execInvShift(execInvRotate(execInvScale(v)));}
00341
00342 Vector<T> execRotateScale(Vector<T> v) { if(!isInverse) return execRotate(execScale(v));
00343 else return execScale(execRotate(v));}
00344 Vector<T> execInvRotateScale(Vector<T> v) { if(!isInverse) return execInvScale(execInvRotate(v));
00345 else return execInvRotate(execInvScale(v));}
00346
00347 Vector<T> execShift(Vector<T> v) { return Vector<T>(v.x+shift.x, v.y+shift.y, v.z+shift.z, (T)0.0, Min(v.c, shift.c));}
00348 Vector<T> execInvShift(Vector<T> v) { return Vector<T>(v.x-shift.x, v.y-shift.y, v.z-shift.z, (T)0.0, Min(v.c, shift.c));}
00349 Vector<T> execScale(Vector<T> v) { return Vector<T>(v.x*scale.x, v.y*scale.y, v.z*scale.z, (T)0.0, Min(v.c, scale.c));}
00350 Vector<T> execInvScale(Vector<T> v) { return Vector<T>(v.x/scale.x, v.y/scale.y, v.z/scale.z, (T)0.0, Min(v.c, scale.c));}
00351 Vector<T> execRotate(Vector<T> v) { return VectorRotation(v, rotate);}
00352 Vector<T> execInvRotate(Vector<T> v){ return VectorInvRotation(v, rotate);}
00353
00354
00355 T* execTrans(T* v) { if(!isInverse) return execShift(execRotate(execScale(v)));
00356 else return execScale(execRotate(execShift(v)));}
00357 T* execInvTrans(T* v) { if(!isInverse) return execInvScale(execInvRotate(execInvShift(v)));
00358 else return execInvShift(execInvRotate(execInvScale(v)));}
00359
00360 T* execRotateScale(T* v) { if(!isInverse) return execRotate(execScale(v));
00361 else return execScale(execRotate(v));}
00362 T* execInvRotateScale(T* v) { if(!isInverse) return execInvScale(execInvRotate(v));
00363 else return execInvRotate(execInvScale(v));}
00364
00365 T* execShift(T* v) { v[0]+=shift.x; v[1]+=shift.y; v[2]+=shift.z; return v;}
00366 T* execInvShift(T* v) { v[0]-=shift.x; v[1]-=shift.y; v[2]-=shift.z; return v;}
00367 T* execScale(T* v) { v[0]*=scale.x; v[1]*=scale.y; v[2]*=scale.z; return v;}
00368 T* execInvScale(T* v) { v[0]/=scale.x; v[1]/=scale.y; v[2]/=scale.z; return v;}
00369 T* execRotate(T* v) { return VectorRotation(v, rotate);}
00370 T* execInvRotate(T* v){ return VectorInvRotation(v, rotate);}
00371 };
00372
00373
00374 template <typename T> inline void freeAffineTrans(AffineTrans<T>*& affine)
00375 {
00376 if (affine!=NULL){
00377 affine->free();
00378 delete(affine);
00379 affine = NULL;
00380 }
00381 }
00382
00383
00384 template <typename T> inline AffineTrans<T>* newAffineTrans(AffineTrans<T> p)
00385 {
00386 AffineTrans<T>* a = new AffineTrans<T>();
00387 a->dup(p);
00388 return a;
00389 }
00390
00391
00395 template <typename T> inline AffineTrans<T> operator * (const AffineTrans<T> a, const AffineTrans<T> b)
00396 {
00397 Quaternion<T> rotate = a.rotate * b.rotate;
00398 Vector<T> shift = a.shift + b.shift;
00399
00400 Vector<T> scale;
00401 scale.set(a.scale.x*b.scale.x, a.scale.y*b.scale.y, a.scale.z*b.scale.z, (T)0.0, Min(a.scale.c, b.scale.c));
00402
00403 AffineTrans<T> affine;
00404 affine.set(scale, rotate, shift, a.isInverse);
00405
00406 return affine;
00407 }
00408
00409
00410
00411
00413
00414
00415
00416 template <typename T> void Quaternion<T>::set(T S, T X, T Y, T Z, T N, T C)
00417 {
00418 s = S;
00419 x = X;
00420 y = Y;
00421 z = Z;
00422 n = N;
00423 c = C;
00424
00425 if (n<=0.0) {
00426 n = (T)sqrt(s*s + x*x + y*y + z*z);
00427 }
00428 }
00429
00430
00431
00432 template <typename T> void Quaternion<T>::normalize()
00433 {
00434 T nrm = (T)sqrt(s*s + x*x + y*y + z*z);
00435
00436 if (nrm>=Zero_Eps) {
00437 s = s/nrm;
00438 x = x/nrm;
00439 y = y/nrm;
00440 z = z/nrm;
00441 n = (T)1.0;
00442 }
00443 else {
00444 init();
00445 }
00446 }
00447
00448
00449
00456 template <typename T> void Quaternion<T>::setRotation(T e, Vector<T> v)
00457 {
00458 if (v.n!=(T)1.0) v.normalize();
00459
00460 if (e>(T)PI) e = e - (T)PI2;
00461 else if (e<-(T)PI) e = (T)PI2 + e;
00462
00463 T s2 = e/(T)2.0;
00464 T sn =(T) sin(s2);
00465 s = (T)cos(s2);
00466 x = v.x*sn;
00467 y = v.y*sn;
00468 z = v.z*sn;
00469 n = (T)v.n;
00470 c = (T)1.0;
00471 }
00472
00473
00474
00484
00485 template <typename T> void Quaternion<T>::setExtEulerYZX(Vector<T> e)
00486 {
00487 Vector<T> ex((T)1.0, (T)0.0, (T)0.0, (T)1.0);
00488 Vector<T> ey((T)0.0, (T)1.0, (T)0.0, (T)1.0);
00489 Vector<T> ez((T)0.0, (T)0.0, (T)1.0, (T)1.0);
00490
00491 Quaternion<T> qx, qy, qz;
00492 qy.setRotation(e.element1(), ey);
00493 qz.setRotation(e.element2(), ez);
00494 qx.setRotation(e.element3(), ex);
00495
00496 (*this) = qx*qz*qy;
00497 if (s<(T)0.0) (*this) = - (*this);
00498 }
00499
00500
00501
00503 template <typename T> void Quaternion<T>::setExtEulerXYZ(Vector<T> e)
00504 {
00505 Vector<T> ex((T)1.0, (T)0.0, (T)0.0, (T)1.0);
00506 Vector<T> ey((T)0.0, (T)1.0, (T)0.0, (T)1.0);
00507 Vector<T> ez((T)0.0, (T)0.0, (T)1.0, (T)1.0);
00508
00509 Quaternion<T> qx, qy, qz;
00510 qx.setRotation(e.element1(), ex);
00511 qy.setRotation(e.element2(), ey);
00512 qz.setRotation(e.element3(), ez);
00513
00514 (*this) = qz*qy*qx;
00515 if (s<(T)0.0) (*this) = - (*this);
00516 }
00517
00518
00519
00521 template <typename T> void Quaternion<T>::setExtEulerZYX(Vector<T> e)
00522 {
00523 Vector<T> ex((T)1.0, (T)0.0, (T)0.0, (T)1.0);
00524 Vector<T> ey((T)0.0, (T)1.0, (T)0.0, (T)1.0);
00525 Vector<T> ez((T)0.0, (T)0.0, (T)1.0, (T)1.0);
00526
00527 Quaternion<T> qx, qy, qz;
00528 qz.setRotation(e.element1(), ez);
00529 qy.setRotation(e.element2(), ey);
00530 qx.setRotation(e.element3(), ex);
00531
00532 (*this) = qx*qy*qz;
00533 if (s<(T)0.0) (*this) = - (*this);
00534 }
00535
00536
00537
00539 template <typename T> void Quaternion<T>::setExtEulerXZY(Vector<T> e)
00540 {
00541 Vector<T> ex((T)1.0, (T)0.0, (T)0.0, (T)1.0);
00542 Vector<T> ey((T)0.0, (T)1.0, (T)0.0, (T)1.0);
00543 Vector<T> ez((T)0.0, (T)0.0, (T)1.0, (T)1.0);
00544
00545 Quaternion<T> qx, qy, qz;
00546 qx.setRotation(e.element1(), ex);
00547 qz.setRotation(e.element2(), ez);
00548 qy.setRotation(e.element3(), ey);
00549
00550 (*this) = qy*qz*qx;
00551 if (s<(T)0.0) (*this) = - (*this);
00552 }
00553
00554
00555
00557 template <typename T> void Quaternion<T>::setExtEulerYXZ(Vector<T> e)
00558 {
00559 Vector<T> ex((T)1.0, (T)0.0, (T)0.0, (T)1.0);
00560 Vector<T> ey((T)0.0, (T)1.0, (T)0.0, (T)1.0);
00561 Vector<T> ez((T)0.0, (T)0.0, (T)1.0, (T)1.0);
00562
00563 Quaternion<T> qx, qy, qz;
00564 qy.setRotation(e.element1(), ey);
00565 qx.setRotation(e.element2(), ex);
00566 qz.setRotation(e.element3(), ez);
00567
00568 (*this) = qz*qx*qy;
00569 if (s<(T)0.0) (*this) = - (*this);
00570 }
00571
00572
00573
00575 template <typename T> void Quaternion<T>::setExtEulerZXY(Vector<T> e)
00576 {
00577 Vector<T> ex((T)1.0, (T)0.0, (T)0.0, (T)1.0);
00578 Vector<T> ey((T)0.0, (T)1.0, (T)0.0, (T)1.0);
00579 Vector<T> ez((T)0.0, (T)0.0, (T)1.0, (T)1.0);
00580
00581 Quaternion<T> qx, qy, qz;
00582 qz.setRotation(e.element1(), ez);
00583 qx.setRotation(e.element2(), ex);
00584 qy.setRotation(e.element3(), ey);
00585
00586 (*this) = qy*qx*qz;
00587 if (s<(T)0.0) (*this) = - (*this);
00588 }
00589
00590
00591
00597 template <typename T> Matrix<T> Quaternion<T>::getRotMatrix()
00598 {
00599 Matrix<T> mtx(2, 3, 3);
00600
00601 if (n!=(T)1.0) normalize();
00602
00603 mtx.element(1, 1) = (T)1.0 - (T)2.0*y*y - (T)2.0*z*z;
00604 mtx.element(1, 2) = (T)2.0*x*y - (T)2.0*s*z;
00605 mtx.element(1, 3) = (T)2.0*x*z + (T)2.0*s*y;
00606 mtx.element(2, 1) = (T)2.0*x*y + (T)2.0*s*z;
00607 mtx.element(2, 2) = (T)1.0 - (T)2.0*x*x - (T)2.0*z*z;
00608 mtx.element(2, 3) = (T)2.0*y*z - (T)2.0*s*x;
00609 mtx.element(3, 1) = (T)2.0*x*z - (T)2.0*s*y;
00610 mtx.element(3, 2) = (T)2.0*y*z + (T)2.0*s*x;
00611 mtx.element(3, 3) = (T)1.0 - (T)2.0*x*x - (T)2.0*y*y;
00612
00613 return mtx;
00614 }
00615
00616
00617
00619 template <typename T> Vector<T> Quaternion<T>::execRotation(Vector<T> v)
00620 {
00621 if (c<(T)0.0) return v;
00622
00623 Quaternion<T> inv = ~(*this);
00624 Quaternion<T> qut = (*this)*(v*inv);
00625 Vector<T> vct = qut.getVector();
00626 vct.d = v.d;
00627
00628 return vct;
00629 }
00630
00631
00632
00634 template <typename T> Vector<T> Quaternion<T>::execInvRotation(Vector<T> v)
00635 {
00636 if (c<(T)0.0) return v;
00637
00638 Quaternion<T> inv = ~(*this);
00639 Quaternion<T> qut = inv*(v*(*this));
00640 Vector<T> vct = qut.getVector();
00641 vct.d = v.d;
00642
00643 return vct;
00644 }
00645
00646
00647
00648
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 template <typename T> Matrix<T> ExtEulerXYZ2RotMatrix(Vector<T> eul)
00660 {
00661 Matrix<T> mtx(2, 3, 3);
00662
00663 T sinx = (T)sin(eul.element1());
00664 T cosx = (T)cos(eul.element1());
00665 T siny = (T)sin(eul.element2());
00666 T cosy = (T)cos(eul.element2());
00667 T sinz = (T)sin(eul.element3());
00668 T cosz = (T)cos(eul.element3());
00669
00670 mtx.element(1, 1) = cosy*cosz;
00671 mtx.element(1, 2) = sinx*siny*cosz - cosx*sinz;
00672 mtx.element(1, 3) = cosx*siny*cosz + sinx*sinz;
00673 mtx.element(2, 1) = cosy*sinz;
00674 mtx.element(2, 2) = sinx*siny*sinz + cosx*cosz;
00675 mtx.element(2, 3) = cosx*siny*sinz - sinx*cosz;
00676 mtx.element(3, 1) = -siny;
00677 mtx.element(3, 2) = sinx*cosy;
00678 mtx.element(3, 3) = cosx*cosy;
00679
00680 return mtx;
00681 }
00682
00683
00684
00685 template <typename T> Matrix<T> ExtEulerZYX2RotMatrix(Vector<T> eul)
00686 {
00687 Matrix<T> mtx(2, 3, 3);
00688
00689 T sinz = (T)sin(eul.element1());
00690 T cosz = (T)cos(eul.element1());
00691 T siny = (T)sin(eul.element2());
00692 T cosy = (T)cos(eul.element2());
00693 T sinx = (T)sin(eul.element3());
00694 T cosx = (T)cos(eul.element3());
00695
00696 mtx.element(1, 1) = cosy*cosz;
00697 mtx.element(1, 2) = -cosy*sinz;
00698 mtx.element(1, 3) = siny;
00699 mtx.element(2, 1) = sinx*siny*cosz + cosx*sinz;
00700 mtx.element(2, 2) = -sinx*siny*sinz + cosx*cosz;
00701 mtx.element(2, 3) = -sinx*cosy;
00702 mtx.element(3, 1) = -cosx*siny*cosz + sinx*sinz;
00703 mtx.element(3, 2) = cosx*siny*sinz + sinx*cosz;
00704 mtx.element(3, 3) = cosx*cosy;
00705
00706 return mtx;
00707 }
00708
00709
00710
00711 template <typename T> Matrix<T> ExtEulerXZY2RotMatrix(Vector<T> eul)
00712 {
00713 Matrix<T> mtx(2, 3, 3);
00714
00715 T sinx = (T)sin(eul.element1());
00716 T cosx = (T)cos(eul.element1());
00717 T sinz = (T)sin(eul.element2());
00718 T cosz = (T)cos(eul.element2());
00719 T siny = (T)sin(eul.element3());
00720 T cosy = (T)cos(eul.element3());
00721
00722 mtx.element(1, 1) = cosy*cosz;
00723 mtx.element(1, 2) = -cosx*cosy*sinz + sinx*siny;
00724 mtx.element(1, 3) = sinx*cosy*sinz + cosx*siny;
00725 mtx.element(2, 1) = sinz;
00726 mtx.element(2, 2) = cosx*cosz;
00727 mtx.element(2, 3) = -sinx*cosz;
00728 mtx.element(3, 1) = -siny*cosz;
00729 mtx.element(3, 2) = cosx*siny*sinz + sinx*cosy;
00730 mtx.element(3, 3) = -sinx*siny*sinz + cosx*cosy;
00731
00732 return mtx;
00733 }
00734
00735
00736
00737 template <typename T> Matrix<T> ExtEulerYZX2RotMatrix(Vector<T> eul)
00738 {
00739 Matrix<T> mtx(2, 3, 3);
00740
00741 T siny = (T)sin(eul.element1());
00742 T cosy = (T)cos(eul.element1());
00743 T sinz = (T)sin(eul.element2());
00744 T cosz = (T)cos(eul.element2());
00745 T sinx = (T)sin(eul.element3());
00746 T cosx = (T)cos(eul.element3());
00747
00748 mtx.element(1, 1) = cosy*cosz;
00749 mtx.element(1, 2) = -sinz;
00750 mtx.element(1, 3) = siny*cosz;
00751 mtx.element(2, 1) = cosx*cosy*sinz + sinx*siny;
00752 mtx.element(2, 2) = cosx*cosz;
00753 mtx.element(2, 3) = cosx*siny*sinz - sinx*cosy;
00754 mtx.element(3, 1) = sinx*cosy*sinz - cosx*siny;
00755 mtx.element(3, 2) = sinx*cosz;
00756 mtx.element(3, 3) = sinx*siny*sinz + cosx*cosy;
00757
00758 return mtx;
00759 }
00760
00761
00762
00763 template <typename T> Matrix<T> ExtEulerZXY2RotMatrix(Vector<T> eul)
00764 {
00765 Matrix<T> mtx(2, 3, 3);
00766
00767 T sinz = (T)sin(eul.element1());
00768 T cosz = (T)cos(eul.element1());
00769 T sinx = (T)sin(eul.element2());
00770 T cosx = (T)cos(eul.element2());
00771 T siny = (T)sin(eul.element3());
00772 T cosy = (T)cos(eul.element3());
00773
00774 mtx.element(1, 1) = sinx*siny*sinz + cosy*cosz;
00775 mtx.element(1, 2) = sinx*siny*cosz - cosy*sinz;
00776 mtx.element(1, 3) = cosx*siny;
00777 mtx.element(2, 1) = cosx*sinz;
00778 mtx.element(2, 2) = cosx*cosz;
00779 mtx.element(2, 3) = -sinx;
00780 mtx.element(3, 1) = sinx*cosy*sinz - siny*cosz;
00781 mtx.element(3, 2) = sinx*cosy*cosz + siny*sinz;
00782 mtx.element(3, 3) = cosx*cosy;
00783
00784 return mtx;
00785 }
00786
00787
00788
00789 template <typename T> Matrix<T> ExtEulerYXZ2RotMatrix(Vector<T> eul)
00790 {
00791 Matrix<T> mtx(2, 3, 3);
00792
00793 T siny = (T)sin(eul.element1());
00794 T cosy = (T)cos(eul.element1());
00795 T sinx = (T)sin(eul.element2());
00796 T cosx = (T)cos(eul.element2());
00797 T sinz = (T)sin(eul.element3());
00798 T cosz = (T)cos(eul.element3());
00799
00800 mtx.element(1, 1) = -sinx*siny*sinz + cosy*cosz;
00801 mtx.element(1, 2) = -cosx*sinz;
00802 mtx.element(1, 3) = sinx*cosy*sinz + siny*cosz;
00803 mtx.element(2, 1) = sinx*siny*cosz + cosy*sinz;
00804 mtx.element(2, 2) = cosx*cosz;
00805 mtx.element(2, 3) = -sinx*cosy*cosz + siny*sinz;
00806 mtx.element(3, 1) = -cosx*siny;
00807 mtx.element(3, 2) = sinx;
00808 mtx.element(3, 3) = cosx*cosy;
00809
00810 return mtx;
00811 }
00812
00813
00814
00815
00816
00817 template <typename T> Vector<T> RotMatrixElements2ExtEulerXYZ(T m11, T m12, T m13, T m21, T m31, T m32, T m33, Vector<T>* vct=NULL)
00818 {
00819 Vector<T> eul((T)0.0, (T)0.0, (T)0.0, (T)0.0, -(T)1.0);
00820 Vector<T> ev[2];
00821 T arctang;
00822
00823 if (m31<-(T)1.0 || m31>(T)1.0) return eul;
00824
00825 if ((T)1.0-m31<(T)Zero_Eps || (T)1.0+m31<(T)Zero_Eps) {
00826 if ((T)1.0-m31<Zero_Eps) {
00827 ev[0].y = ev[1].y = -(T)PI_DIV2;
00828 ev[0].z = (T)0.0;
00829 ev[1].z = (T)PI_DIV2;
00830 arctang = (T)atan2(-m12, -m13);
00831 ev[0].x = arctang - ev[0].z;
00832 ev[1].x = arctang - ev[1].z;
00833 }
00834 else {
00835 ev[0].y = ev[1].y = (T)PI_DIV2;
00836 ev[0].z = (T)0.0;
00837 ev[1].z = (T)PI_DIV2;
00838 arctang = (T)atan2(m12, m13);
00839 ev[0].x = arctang + ev[0].z;
00840 ev[1].x = arctang + ev[1].z;
00841 }
00842 }
00843
00844 else {
00845 ev[0].y = -(T)asin(m31);
00846 if (ev[0].y>=(T)0.0) ev[1].y = (T)PI - ev[0].y;
00847 else ev[1].y = - (T)PI - ev[0].y;
00848
00849 T cy1 = (T)cos(ev[0].y);
00850 T cy2 = (T)cos(ev[1].y);
00851 if (Xabs(cy1)<(T)Zero_Eps || Xabs(cy2)<(T)Zero_Eps) return eul;
00852
00853 ev[0].x = (T)atan2(m32/cy1, m33/cy1);
00854 ev[0].z = (T)atan2(m21/cy1, m11/cy1);
00855
00856 if (ev[0].x>=(T)0.0) ev[1].x = ev[0].x - (T)PI;
00857 else ev[1].x = ev[0].x + (T)PI;
00858 if (ev[0].z>=(T)0.0) ev[1].z = ev[0].z - (T)PI;
00859 else ev[1].z = ev[0].z + (T)PI;
00860 }
00861
00862
00863
00864 if (vct!=NULL) {
00865 vct[0].set(ev[0].x, ev[0].y, ev[0].z);
00866 vct[1].set(ev[1].x, ev[1].y, ev[1].z);
00867 }
00868 eul.set(ev[0].x, ev[0].y, ev[0].z);
00869
00870 return eul;
00871 }
00872
00873
00874 template <typename T> Vector<T> RotMatrixElements2ExtEulerZYX(T m11, T m12, T m13, T m21, T m23, T m31, T m33, Vector<T>* vct=NULL)
00875 {
00876 Vector<T> eul((T)0.0, (T)0.0, (T)0.0, (T)0.0, -(T)1.0);
00877 Vector<T> ev[2];
00878 T arctang;
00879
00880 if (m13<-(T)1.0 || m13>(T)1.0) return eul;
00881
00882 if ((T)1.0-m13<(T)Zero_Eps || (T)1.0+m13<(T)Zero_Eps) {
00883 if ((T)1.0-m13<(T)Zero_Eps) {
00884 ev[0].y = ev[1].y = (T)PI_DIV2;
00885 ev[0].z = (T)0.0;
00886 ev[1].z = (T)PI_DIV2;
00887 arctang = (T)atan2(m21, -m31);
00888 ev[0].x = (T)arctang - ev[0].z;
00889 ev[1].x = (T)arctang - ev[1].z;
00890 }
00891 else {
00892 ev[0].y = ev[1].y = -(T)PI_DIV2;
00893 ev[0].z = (T)0.0;
00894 ev[1].z = (T)PI_DIV2;
00895 arctang = (T)atan2(-m21, m31);
00896 ev[0].x = (T)arctang + ev[0].z;
00897 ev[1].x = (T)arctang + ev[1].z;
00898 }
00899 }
00900
00901 else {
00902 ev[0].y = (T)asin(m13);
00903 if (ev[0].y>=0.0) ev[1].y = (T)PI - ev[0].y;
00904 else ev[1].y = -(T)PI - ev[0].y;
00905
00906 T cy1 = (T)cos(ev[0].y);
00907 T cy2 = (T)cos(ev[1].y);
00908 if (Xabs(cy1)<Zero_Eps || Xabs(cy2)<Zero_Eps) return eul;
00909
00910 ev[0].x = atan2(-m23/cy1, m33/cy1);
00911 ev[0].z = atan2(-m12/cy1, m11/cy1);
00912
00913 if (ev[0].x>=(T)0.0) ev[1].x = ev[0].x - (T)PI;
00914 else ev[1].x = ev[0].x + (T)PI;
00915 if (ev[0].z>=(T)0.0) ev[1].z = ev[0].z - (T)PI;
00916 else ev[1].z = ev[0].z + (T)PI;
00917 }
00918
00919
00920
00921 if (vct!=NULL) {
00922 vct[0].set(ev[0].z, ev[0].y, ev[0].x);
00923 vct[1].set(ev[1].z, ev[1].y, ev[1].x);
00924 }
00925 eul.set(ev[0].z, ev[0].y, ev[0].x);
00926
00927 return eul;
00928 }
00929
00930
00931 template <typename T> Vector<T> RotMatrixElements2ExtEulerXZY(T m11, T m12, T m13, T m21, T m22, T m23, T m31, Vector<T>* vct=NULL)
00932 {
00933 Vector<T> eul((T)0.0, (T)0.0, (T)0.0, (T)0.0, -(T)1.0);
00934 Vector<T> ev[2];
00935 T arctang;
00936
00937 if (m21<-(T)1.0 || m21>(T)1.0) return eul;
00938
00939 if ((T)1.0-m21<(T)Zero_Eps || (T)1.0+m21<(T)Zero_Eps) {
00940 if ((T)1.0-m21<(T)Zero_Eps) {
00941 ev[0].z = ev[1].z = (T)PI_DIV2;
00942 ev[0].y = (T)0.0;
00943 ev[1].y = (T)PI_DIV2;
00944 arctang = (T)atan2(m13, -m12);
00945 ev[0].x = arctang - ev[0].y;
00946 ev[1].x = arctang - ev[1].y;
00947 }
00948 else {
00949 ev[0].z = ev[1].y = -(T)PI_DIV2;
00950 ev[0].y = (T)0.0;
00951 ev[1].y = (T)PI_DIV2;
00952 arctang = (T)atan2(-m13, m12);
00953 ev[0].x = arctang + ev[0].y;
00954 ev[1].x = arctang + ev[1].y;
00955 }
00956 }
00957
00958 else {
00959 ev[0].z = (T)asin(m21);
00960 if (ev[0].z>=(T)0.0) ev[1].z = (T)PI - ev[0].z;
00961 else ev[1].z = -(T)PI - ev[0].z;
00962
00963 T cz1 = (T)cos(ev[0].z);
00964 T cz2 = (T)cos(ev[1].z);
00965 if (Xabs(cz1)<(T)Zero_Eps || Xabs(cz2)<(T)Zero_Eps) return eul;
00966
00967 ev[0].x = (T)atan2(-m23/cz1, m22/cz1);
00968 ev[0].y = (T)atan2(-m31/cz1, m11/cz1);
00969
00970 if (ev[0].x>=(T)0.0) ev[1].x = ev[0].x - (T)PI;
00971 else ev[1].x = ev[0].x + (T)PI;
00972 if (ev[0].y>=(T)0.0) ev[1].y = ev[0].y - (T)PI;
00973 else ev[1].y = ev[0].y + (T)PI;
00974 }
00975
00976
00977
00978 if (vct!=NULL) {
00979 vct[0].set(ev[0].x, ev[0].z, ev[0].y);
00980 vct[1].set(ev[1].x, ev[1].z, ev[1].y);
00981 }
00982 eul.set(ev[0].x, ev[0].z, ev[0].y);
00983
00984 return eul;
00985 }
00986
00987
00988 template <typename T> Vector<T> RotMatrixElements2ExtEulerYZX(T m11, T m12, T m13, T m21, T m22, T m31, T m32, Vector<T>* vct=NULL)
00989 {
00990 Vector<T> eul((T)0.0, (T)0.0, (T)0.0, (T)0.0, -(T)1.0);
00991 Vector<T> ev[2];
00992 T arctang;
00993
00994 if (m12<-(T)1.0 || m12>(T)1.0) return eul;
00995
00996 if ((T)1.0-m12<(T)Zero_Eps || (T)1.0+m12<(T)Zero_Eps) {
00997 if (1.0-m12<Zero_Eps) {
00998 ev[0].z = ev[1].z = -(T)PI_DIV2;
00999 ev[0].y = (T)0.0;
01000 ev[1].y = (T)PI_DIV2;
01001 arctang = (T)atan2(-m31, -m21);
01002 ev[0].x = arctang - ev[0].y;
01003 ev[1].x = arctang - ev[1].y;
01004 }
01005 else {
01006 ev[0].z = ev[1].y = (T)PI_DIV2;
01007 ev[0].y = (T)0.0;
01008 ev[1].y = (T)PI_DIV2;
01009 arctang = (T)atan2(m31, m21);
01010 ev[0].x = arctang + ev[0].y;
01011 ev[1].x = arctang + ev[1].y;
01012 }
01013 }
01014
01015 else {
01016 ev[0].z = -(T)asin(m12);
01017 if (ev[0].z>=0.0) ev[1].z = (T)PI - ev[0].z;
01018 else ev[1].z = -(T)PI - ev[0].z;
01019
01020 T cz1 = (T)cos(ev[0].z);
01021 T cz2 = (T)cos(ev[1].z);
01022 if (Xabs(cz1)<(T)Zero_Eps || Xabs(cz2)<(T)Zero_Eps) return eul;
01023
01024 ev[0].x = (T)atan2(m32/cz1, m22/cz1);
01025 ev[0].y = (T)atan2(m13/cz1, m11/cz1);
01026
01027 if (ev[0].x>=(T)0.0) ev[1].x = ev[0].x - (T)PI;
01028 else ev[1].x = ev[0].x + (T)PI;
01029 if (ev[0].y>=(T)0.0) ev[1].y = ev[0].y - (T)PI;
01030 else ev[1].y = ev[0].y + (T)PI;
01031 }
01032
01033
01034
01035 if (vct!=NULL) {
01036 vct[0].set(ev[0].y, ev[0].z, ev[0].x);
01037 vct[1].set(ev[1].y, ev[1].z, ev[1].x);
01038 }
01039 eul.set(ev[0].y, ev[0].z, ev[0].x);
01040
01041 return eul;
01042 }
01043
01044
01045 template <typename T> Vector<T> RotMatrixElements2ExtEulerYXZ(T m12, T m21, T m22, T m23, T m31, T m32, T m33, Vector<T>* vct=NULL)
01046 {
01047 Vector<T> eul((T)0.0, (T)0.0, (T)0.0, (T)0.0, -(T)1.0);
01048 Vector<T> ev[2];
01049 T arctang;
01050
01051 if (m32<-(T)1.0 || m32>(T)1.0) return eul;
01052
01053 if ((T)1.0-m32<(T)Zero_Eps || (T)1.0+m32<(T)Zero_Eps) {
01054 if ((T)1.0-m32<(T)Zero_Eps) {
01055 ev[0].x = ev[1].x = (T)PI_DIV2;
01056 ev[0].z = (T)0.0;
01057 ev[1].z = (T)PI_DIV2;
01058 arctang = (T)atan2(m21, -m23);
01059 ev[0].y = arctang - ev[0].z;
01060 ev[1].y = arctang - ev[1].z;
01061 }
01062 else {
01063 ev[0].x = ev[1].x = -(T)PI_DIV2;
01064 ev[0].z = (T)0.0;
01065 ev[1].z = (T)PI_DIV2;
01066 arctang = (T)atan2(-m21, m23);
01067 ev[0].y = arctang + ev[0].z;
01068 ev[1].y = arctang + ev[1].z;
01069 }
01070 }
01071
01072 else {
01073 ev[0].x = (T)asin(m32);
01074 if (ev[0].x>=0.0) ev[1].x = (T)PI - ev[0].x;
01075 else ev[1].x = -(T)PI - ev[0].x;
01076
01077 T cx1 = (T)cos(ev[0].x);
01078 T cx2 = (T)cos(ev[1].x);
01079 if (Xabs(cx1)<(T)Zero_Eps || Xabs(cx2)<(T)Zero_Eps) return eul;
01080
01081 ev[0].y = (T)atan2(-m31/cx1, m33/cx1);
01082 ev[0].z = (T)atan2(-m12/cx1, m22/cx1);
01083
01084 if (ev[0].y>=(T)0.0) ev[1].y = ev[0].y - (T)PI;
01085 else ev[1].y = ev[0].y + (T)PI;
01086 if (ev[0].z>=(T)0.0) ev[1].z = ev[0].z - (T)PI;
01087 else ev[1].z = ev[0].z + (T)PI;
01088 }
01089
01090
01091
01092 if (vct!=NULL) {
01093 vct[0].set(ev[0].y, ev[0].x, ev[0].z);
01094 vct[1].set(ev[1].y, ev[1].x, ev[1].z);
01095 }
01096 eul.set(ev[0].y, ev[0].x, ev[0].z);
01097
01098 return eul;
01099 }
01100
01101
01102 template <typename T> Vector<T> RotMatrixElements2ExtEulerZXY(T m12, T m13, T m21, T m22, T m23, T m32, T m33, Vector<T>* vct=NULL)
01103 {
01104 Vector<T> eul((T)0.0, (T)0.0, (T)0.0, (T)0.0, -(T)1.0);
01105 Vector<T> ev[2];
01106 T arctang;
01107
01108 if (m23<-(T)1.0 || m23>(T)1.0) return eul;
01109
01110 if ((T)1.0-m23<(T)Zero_Eps || (T)1.0+m23<(T)Zero_Eps) {
01111 if ((T)1.0-m23<(T)Zero_Eps) {
01112 ev[0].x = ev[1].x = -(T)PI_DIV2;
01113 ev[0].z = (T)0.0;
01114 ev[1].z = (T)PI_DIV2;
01115 arctang = (T)atan2(-m12, -m32);
01116 ev[0].y = arctang - ev[0].z;
01117 ev[1].y = arctang - ev[1].z;
01118 }
01119 else {
01120 ev[0].x = ev[1].x = (T)PI_DIV2;
01121 ev[0].z = (T)0.0;
01122 ev[1].z = (T)PI_DIV2;
01123 arctang = (T)atan2(m12, m32);
01124 ev[0].y = arctang + ev[0].z;
01125 ev[1].y = arctang + ev[1].z;
01126 }
01127 }
01128
01129 else {
01130 ev[0].x = -(T)asin(m23);
01131 if (ev[0].x>=(T)0.0) ev[1].x = (T)PI - ev[0].x;
01132 else ev[1].x = -(T)PI - ev[0].x;
01133
01134 T cx1 = (T)cos(ev[0].x);
01135 T cx2 = (T)cos(ev[1].x);
01136 if (Xabs(cx1)<(T)Zero_Eps || Xabs(cx2)<(T)Zero_Eps) return eul;
01137
01138 ev[0].y = (T)atan2(m13/cx1, m33/cx1);
01139 ev[0].z = (T)atan2(m21/cx1, m22/cx1);
01140
01141 if (ev[0].y>=(T)0.0) ev[1].y = ev[0].y - (T)PI;
01142 else ev[1].y = ev[0].y + (T)PI;
01143 if (ev[0].z>=(T)0.0) ev[1].z = ev[0].z - (T)PI;
01144 else ev[1].z = ev[0].z + (T)PI;
01145 }
01146
01147
01148
01149 if (vct!=NULL) {
01150 vct[0].set(ev[0].z, ev[0].x, ev[0].y);
01151 vct[1].set(ev[1].z, ev[1].x, ev[1].y);
01152 }
01153 eul.set(ev[0].z, ev[0].x, ev[0].y);
01154
01155 return eul;
01156 }
01157
01158
01159
01160
01161
01162 template <typename T> Vector<T> RotMatrix2ExtEulerXYZ(Matrix<T> mtx, Vector<T>* vct=NULL)
01163 {
01164 T m11 = mtx.element(1, 1);
01165 T m12 = mtx.element(1, 2);
01166 T m13 = mtx.element(1, 3);
01167 T m21 = mtx.element(2, 1);
01168 T m31 = mtx.element(3, 1);
01169 T m32 = mtx.element(3, 2);
01170 T m33 = mtx.element(3, 3);
01171
01172 Vector<T> eul = RotMatrixElements2ExtEulerXYZ<T>(m11, m12, m13, m21, m31, m32, m33, vct);
01173
01174 return eul;
01175 }
01176
01177
01178
01179 template <typename T> Vector<T> RotMatrix2ExtEulerZYX(Matrix<T> mtx, Vector<T>* vct)
01180 {
01181 T m11 = mtx.element(1, 1);
01182 T m12 = mtx.element(1, 2);
01183 T m13 = mtx.element(1, 3);
01184 T m21 = mtx.element(2, 1);
01185 T m23 = mtx.element(2, 3);
01186 T m31 = mtx.element(3, 1);
01187 T m33 = mtx.element(3, 3);
01188
01189 Vector<T> eul = RotMatrixElements2ExtEulerZYX<T>(m11, m12, m13, m21, m23, m31, m33, vct);
01190
01191 return eul;
01192 }
01193
01194
01195 template <typename T> Vector<T> RotMatrix2ExtEulerXZY(Matrix<T> mtx, Vector<T>* vct=NULL)
01196 {
01197 T m11 = mtx.element(1, 1);
01198 T m12 = mtx.element(1, 2);
01199 T m13 = mtx.element(1, 3);
01200 T m21 = mtx.element(2, 1);
01201 T m22 = mtx.element(2, 2);
01202 T m23 = mtx.element(2, 3);
01203 T m31 = mtx.element(3, 1);
01204
01205 Vector<T> eul = RotMatrixElements2ExtEulerXZY<T>(m11, m12, m13, m21, m22, m23, m31, vct);
01206
01207 return eul;
01208 }
01209
01210
01211 template <typename T> Vector<T> RotMatrix2ExtEulerYZX(Matrix<T> mtx, Vector<T>* vct=NULL)
01212 {
01213 T m11 = mtx.element(1, 1);
01214 T m12 = mtx.element(1, 2);
01215 T m13 = mtx.element(1, 3);
01216 T m21 = mtx.element(2, 1);
01217 T m22 = mtx.element(2, 2);
01218 T m31 = mtx.element(3, 1);
01219 T m32 = mtx.element(3, 2);
01220
01221 Vector<T> eul = RotMatrixElements2ExtEulerYZX<T>(m11, m12, m13, m21, m22, m31, m32, vct);
01222
01223 return eul;
01224 }
01225
01226
01227 template <typename T> Vector<T> RotMatrix2ExtEulerYXZ(Matrix<T> mtx, Vector<T>* vct=NULL)
01228 {
01229 T m12 = mtx.element(1, 2);
01230 T m21 = mtx.element(2, 1);
01231 T m22 = mtx.element(2, 2);
01232 T m23 = mtx.element(2, 3);
01233 T m31 = mtx.element(3, 1);
01234 T m32 = mtx.element(3, 2);
01235 T m33 = mtx.element(3, 3);
01236
01237 Vector<T> eul = RotMatrixElements2ExtEulerYXZ<T>(m12, m21, m22, m23, m31, m32, m33, vct);
01238
01239 return eul;
01240 }
01241
01242
01243 template <typename T> Vector<T> RotMatrix2ExtEulerZXY(Matrix<T> mtx, Vector<T>* vct=NULL)
01244 {
01245 T m12 = mtx.element(1, 2);
01246 T m13 = mtx.element(1, 3);
01247 T m21 = mtx.element(2, 1);
01248 T m22 = mtx.element(2, 2);
01249 T m23 = mtx.element(2, 3);
01250 T m32 = mtx.element(3, 2);
01251 T m33 = mtx.element(3, 3);
01252
01253 Vector<T> eul = RotMatrixElements2ExtEulerZXY<T>(m12, m13, m21, m22, m23, m32, m33, vct);
01254
01255 return eul;
01256 }
01257
01258
01259
01260
01261
01262
01263 template <typename T> Vector<T> Quaternion2ExtEulerXYZ(Quaternion<T> qut, Vector<T>* vct)
01264 {
01265 Matrix<T> mtx = qut.getRotMatrix();
01266 Vector<T> eul = RotMatrix2ExtEulerXYZ<T>(mtx, vct);
01267 mtx.free();
01268
01269 return eul;
01270 }
01271
01272
01273
01274 template <typename T> Vector<T> Quaternion2ExtEulerZYX(Quaternion<T> qut, Vector<T>* vct)
01275 {
01276 Matrix<T> mtx = qut.getRotMatrix();
01277 Vector<T> eul = RotMatrix2ExtEulerZYX(mtx, vct);
01278 mtx.free();
01279
01280 return eul;
01281 }
01282
01283
01284
01285 template <typename T> Vector<T> Quaternion2ExtEulerXZY(Quaternion<T> qut, Vector<T>* vct)
01286 {
01287 Matrix<T> mtx = qut.getRotMatrix();
01288 Vector<T> eul = RotMatrix2ExtEulerXZY(mtx, vct);
01289 mtx.free();
01290
01291 return eul;
01292 }
01293
01294
01295
01296 template <typename T> Vector<T> Quaternion2ExtEulerYZX(Quaternion<T> qut, Vector<T>* vct)
01297 {
01298 Matrix<T> mtx = qut.getRotMatrix();
01299 Vector<T> eul = RotMatrix2ExtEulerYZX(mtx, vct);
01300 mtx.free();
01301
01302 return eul;
01303 }
01304
01305
01306
01307 template <typename T> Vector<T> Quaternion2ExtEulerYXZ(Quaternion<T> qut, Vector<T>* vct)
01308 {
01309 Matrix<T> mtx = qut.getRotMatrix();
01310 Vector<T> eul = RotMatrix2ExtEulerYXZ(mtx, vct);
01311 mtx.free();
01312
01313 return eul;
01314 }
01315
01316
01317
01318 template <typename T> Vector<T> Quaternion2ExtEulerZXY(Quaternion<T> qut, Vector<T>* vct)
01319 {
01320 Matrix<T> mtx = qut.getRotMatrix();
01321 Vector<T> eul = RotMatrix2ExtEulerZXY(mtx, vct);
01322 mtx.free();
01323
01324 return eul;
01325 }
01326
01327
01328
01329
01330
01331 template <typename T> Quaternion<T> RotMatrix2Quaternion(Matrix<T> mtx)
01332 {
01333 Quaternion<T> qut;
01334 Vector<T> xyz = RotMatrix2ExtEulerXYZ(mtx);
01335 qut.setExtEulerXYZ(xyz);
01336
01337 return qut;
01338 }
01339
01340
01341
01342
01344
01345
01346
01352 template <typename T> Vector<T> VectorRotation(Vector<T> v, Quaternion<T> q)
01353 {
01354 Vector<T> vect;
01355
01356 vect.x = (q.s*q.s + q.x*q.x - q.y*q.y -q.z*q.z)*v.x +
01357 ((T)2.0*q.x*q.y - (T)2.0*q.s*q.z)*v.y +
01358 ((T)2.0*q.x*q.z + (T)2.0*q.s*q.y)*v.z;
01359
01360 vect.y = ((T)2.0*q.x*q.y + (T)2.0*q.s*q.z)*v.x +
01361 (q.s*q.s - q.x*q.x + q.y*q.y - q.z*q.z)*v.y +
01362 ((T)2.0*q.y*q.z - (T)2.0*q.s*q.x)*v.z;
01363
01364 vect.z = ((T)2.0*q.x*q.z - (T)2.0*q.s*q.y)*v.x +
01365 ((T)2.0*q.y*q.z + (T)2.0*q.s*q.x)*v.y +
01366 (q.s*q.s - q.x*q.x - q.y*q.y + q.z*q.z)*v.z;
01367
01368 return vect;
01369 }
01370
01371
01372
01373 template <typename T> Vector<T> VectorInvRotation(Vector<T> v, Quaternion<T> q)
01374 {
01375 Vector<T> vect;
01376
01377 vect.x = (q.s*q.s + q.x*q.x - q.y*q.y -q.z*q.z)*v.x +
01378 ((T)2.0*q.x*q.y + (T)2.0*q.s*q.z)*v.y +
01379 ((T)2.0*q.x*q.z - (T)2.0*q.s*q.y)*v.z;
01380
01381 vect.y = ((T)2.0*q.x*q.y - (T)2.0*q.s*q.z)*v.x +
01382 (q.s*q.s - q.x*q.x + q.y*q.y - q.z*q.z)*v.y +
01383 ((T)2.0*q.y*q.z + (T)2.0*q.s*q.x)*v.z;
01384
01385 vect.z = ((T)2.0*q.x*q.z + (T)2.0*q.s*q.y)*v.x +
01386 ((T)2.0*q.y*q.z - (T)2.0*q.s*q.x)*v.y +
01387 (q.s*q.s - q.x*q.x - q.y*q.y + q.z*q.z)*v.z;
01388
01389 return vect;
01390 }
01391
01392
01393
01394 template <typename T> T* VectorRotation(T* v, Quaternion<T> q)
01395 {
01396 T x, y, z;
01397
01398 x = (q.s*q.s + q.x*q.x - q.y*q.y -q.z*q.z)*v[0] +
01399 ((T)2.0*q.x*q.y - (T)2.0*q.s*q.z)*v[1] +
01400 ((T)2.0*q.x*q.z + (T)2.0*q.s*q.y)*v[2];
01401
01402 y = ((T)2.0*q.x*q.y + (T)2.0*q.s*q.z)*v[0] +
01403 (q.s*q.s - q.x*q.x + q.y*q.y - q.z*q.z)*v[1] +
01404 ((T)2.0*q.y*q.z - (T)2.0*q.s*q.x)*v[2];
01405
01406 z = ((T)2.0*q.x*q.z - (T)2.0*q.s*q.y)*v[0] +
01407 ((T)2.0*q.y*q.z + (T)2.0*q.s*q.x)*v[1] +
01408 (q.s*q.s - q.x*q.x - q.y*q.y + q.z*q.z)*v[2];
01409
01410 v[0] = x;
01411 v[1] = y;
01412 v[2] = z;
01413
01414 return v;
01415 }
01416
01417
01418
01419 template <typename T> T* VectorInvRotation(T* v, Quaternion<T> q)
01420 {
01421 T x, y, z;
01422
01423 x = (q.s*q.s + q.x*q.x - q.y*q.y -q.z*q.z)*v[0] +
01424 ((T)2.0*q.x*q.y + (T)2.0*q.s*q.z)*v[1] +
01425 ((T)2.0*q.x*q.z - (T)2.0*q.s*q.y)*v[2];
01426
01427 y = ((T)2.0*q.x*q.y - (T)2.0*q.s*q.z)*v[0] +
01428 (q.s*q.s - q.x*q.x + q.y*q.y - q.z*q.z)*v[1] +
01429 ((T)2.0*q.y*q.z + (T)2.0*q.s*q.x)*v[2];
01430
01431 z = ((T)2.0*q.x*q.z + (T)2.0*q.s*q.y)*v[0] +
01432 ((T)2.0*q.y*q.z - (T)2.0*q.s*q.x)*v[1] +
01433 (q.s*q.s - q.x*q.x - q.y*q.y + q.z*q.z)*v[2];
01434
01435 v[0] = x;
01436 v[1] = y;
01437 v[2] = z;
01438
01439 return v;
01440 }
01441
01442
01443
01444 template <typename T> Quaternion<T> V2VQuaternion(Vector<T> a, Vector<T> b)
01445 {
01446 Quaternion<T> qut((T)1.0, (T)0.0, (T)0.0, (T)0.0, (T)1.0);
01447
01448 a.normalize();
01449 b.normalize();
01450 if (a.n<(T)Zero_Eps || b.n<(T)Zero_Eps) return qut;
01451
01452 Vector<T> nr = a^b;
01453 nr.normalize();
01454
01455 T cs2 = (a*b)/(T)2.0;
01456
01457 T sn;
01458 if (cs2>(T)0.5) sn = (T)0.0;
01459 else sn = (T)sqrt(0.5 - cs2);
01460
01461 if (Xabs(sn-(T)1.0)<(T)Zero_Eps) {
01462 Vector<T> c = a + b;
01463 if (c.norm()<(T)1.0) {
01464 qut.setRotation(PI, nr);
01465 if (nr.n<Zero_Eps) {
01466 qut.s = (T)0.0;
01467 qut.n = (T)0.0;
01468 qut.c = -(T)1.0;
01469 }
01470 }
01471 else {
01472 qut.setRotation((T)0.0, nr);
01473 }
01474 return qut;
01475 }
01476
01477 T cs;
01478 if (cs2<-(T)0.5) cs = (T)0.0;
01479 else cs = (T)sqrt(0.5 + cs2);
01480
01481
01482 if (cs>(T)1.0) qut.set((T)1.0, (T)0.0, (T)0.0, (T)0.0, (T)1.0, -(T)1.0);
01483 else qut.set(cs, nr.x*sn, nr.y*sn, nr.z*sn, (T)1.0, (T)Min(a.c, b.c));
01484
01485 return qut;
01486 }
01487
01488
01489
01490 template <typename T> Quaternion<T> PPPQuaternion(Vector<T> a, Vector<T> b, Vector<T> c)
01491 {
01492 Quaternion<T> qut((T)1.0, (T)0.0, (T)0.0, (T)0.0, (T)1.0);
01493
01494 if (a.c<(T)0.0 || b.c<(T)0.0 || c.c<(T)0.0) return qut;
01495
01496 qut = V2VQuaternion<T>(b-a, c-b);
01497 return qut;
01498 }
01499
01500
01501
01502 template <typename T> Quaternion<T> VPPQuaternion(Vector<T> a, Vector<T> b, Vector<T> c)
01503 {
01504 Quaternion<T> qut((T)1.0, (T)0.0, (T)0.0, (T)0.0, (T)1.0);
01505
01506 if (a.c<(T)0.0 || b.c<(T)0.0 || c.c<(T)0.0) return qut;
01507
01508 qut = V2VQuaternion<T>(a, c-b);
01509 return qut;
01510 }
01511
01512
01513
01514 template <typename T> Quaternion<T> PPVQuaternion(Vector<T> a, Vector<T> b, Vector<T> c)
01515 {
01516 Quaternion<T> qut((T)1.0, (T)0.0, (T)0.0, (T)0.0, (T)1.0);
01517
01518 if (a.c<(T)0.0 || b.c<(T)0.0 || c.c<(T)0.0) return qut;
01519
01520 qut = V2VQuaternion<T>(b-a, c);
01521 return qut;
01522 }
01523
01524
01525
01542 template <typename T> Quaternion<T> SlerpQuaternion(Quaternion<T> qa, Quaternion<T> qb, T t)
01543 {
01544 if (qa.n!=(T)1.0) qa.normalize();
01545 if (qb.n!=(T)1.0) qb.normalize();
01546
01547
01548 T dot;
01549 Quaternion<T> qc;
01550
01552
01553 Vector<T> va = qa.getVector();
01554 Vector<T> vb = qb.getVector();
01555 va.normalize();
01556 vb.normalize();
01557
01558
01559 dot = va*vb;
01560 if (dot>(T)1.0) dot = 1.0;
01561 else if (dot<-(T)1.0) dot = -1.0;
01562
01563
01564 if (dot>(T)1.0-Sin_Tolerance) {
01565 T anga = qa.getMathAngle();
01566 T angb = qb.getMathAngle();
01567 T angd = angb - anga;
01568 if (angd<-(T)PI) angd += (T)PI2;
01569 else if (angd>(T)PI) angd -= (T)PI2;
01570
01571 T angc = anga + t*angd;
01572 qc.setRotation(angc, va);
01573 qc.normalize();
01574 return qc;
01575 }
01576
01577
01578
01579 else if (dot<-(T)0.99) {
01580 T anga = qa.getMathAngle();
01581 T angb = - qb.getMathAngle();
01582 T angd = angb - anga;
01583 if (angd<-(T)PI) angd += (T)PI2;
01584 else if (angd>(T)PI) angd -= (T)PI2;
01585
01586 T angc = anga + t*angd;
01587 qc.setRotation(angc, va);
01588 qc.normalize();
01589 return qc;
01590 }
01591
01592
01593 dot = qa.x*qb.x + qa.y*qb.y + qa.z*qb.z + qa.s*qb.s;
01594 if (dot>(T)1.0) dot = (T)1.0;
01595 else if (dot<(T)0.0) {
01596 if (t<=(T)0.5) return qa;
01597 else return qb;
01598 }
01599
01600
01601
01602 T th = (T)acos(dot);
01603 T sn = (T)sin(th);
01604 if (Xabs(sn)<(T)Sin_Tolerance) return qa;
01605
01606
01607 qc = qa*((T)sin(((T)1.0-t)*th)/sn) + qb*((T)sin(t*th)/sn);
01608 qc.normalize();
01609
01610 return qc;
01611 }
01612
01613
01614
01615
01617
01618
01619
01620
01621 template <typename T> void AffineTrans<T>::dup(AffineTrans<T> a)
01622 {
01623 *this = a;
01624 matrix.dup(a.matrix);
01625
01626 return;
01627 }
01628
01629
01630
01631
01632 template <typename T> Matrix<T> AffineTrans<T>::getRotMatrix(void)
01633 {
01634 Matrix<T> mt;
01635
01636 if (matrix.element(4,4)==(T)1.0) {
01637 mt.init(2, 3, 3);
01638 for (int j=1; j<=3; j++) {
01639 for (int i=1; i<=3; i++) {
01640 mt.element(i, j) = matrix.element(i, j);
01641 }
01642 }
01643 }
01644 else {
01645 mt = rotate.getRotMatrix();
01646 }
01647 return mt;
01648 }
01649
01650
01651
01652
01653 template <typename T> AffineTrans<T> AffineTrans<T>::getInvAffine(void)
01654 {
01655 AffineTrans<T> affine;
01656 if (!isNormal()) return affine;
01657
01658 Matrix<T> rsz(2, 3, 3);
01659 rsz.element(1,1) = (T)1.0/scale.x;
01660 rsz.element(2,2) = (T)1.0/scale.y;
01661 rsz.element(3,3) = (T)1.0/scale.z;
01662
01663 Matrix<T> rmt = rsz*(~rotate).getRotMatrix();
01664
01665 affine.matrix.element(4,4) = (T)1.0;
01666 for (int j=1; j<=3; j++) {
01667 for (int i=1; i<=3; i++) {
01668 affine.matrix.element(i,j) = rmt.element(i,j);
01669 }
01670 }
01671 rsz.free();
01672 rmt.free();
01673
01674 Matrix<T> rst(2, 4, 4);
01675 rst.element(1,1) = rst.element(2,2) = rst.element(3,3) = rst.element(4,4) = (T)1.0;
01676 rst.element(1,4) = -shift.x;
01677 rst.element(2,4) = -shift.y;
01678 rst.element(3,4) = -shift.z;
01679
01680 affine.matrix = affine.matrix*rst;
01681 affine.isInverse = !isInverse;
01682 affine.computeComponents();
01683
01684 rst.free();
01685
01686 return affine;
01687 }
01688
01689
01690
01691
01692 template <typename T> void AffineTrans<T>::computeMatrix(bool with_scale)
01693 {
01694 Matrix<T> sz(2, 3, 3);
01695 if (with_scale) {
01696 sz.element(1,1) = scale.x;
01697 sz.element(2,2) = scale.y;
01698 sz.element(3,3) = scale.z;
01699 }
01700 else {
01701 sz.element(1,1) = (T)1.0;
01702 sz.element(2,2) = (T)1.0;
01703 sz.element(3,3) = (T)1.0;
01704 }
01705
01706 matrix.clear();
01707 Matrix<T> mt = rotate.getRotMatrix()*sz;
01708 for (int j=1; j<=3; j++) {
01709 for (int i=1; i<=3; i++) {
01710 matrix.element(i, j) = mt.element(i, j);
01711 }
01712 }
01713 sz.free();
01714 mt.free();
01715
01716 matrix.element(1,4) = shift.x;
01717 matrix.element(2,4) = shift.y;
01718 matrix.element(3,4) = shift.z;
01719 matrix.element(4,4) = (T)1.0;
01720
01721 return;
01722 }
01723
01724
01725
01726
01727 template <typename T> void AffineTrans<T>::computeComponents(void)
01728 {
01729 T sx, sy, sz;
01730 sx = sy = sz = (T)0.0;
01731 if (!isInverse) {
01732 for (int i=1; i<=3; i++) {
01733 sx += matrix.element(i,1)*matrix.element(i,1);
01734 sy += matrix.element(i,2)*matrix.element(i,2);
01735 sz += matrix.element(i,3)*matrix.element(i,3);
01736 }
01737 }
01738 else {
01739 for (int i=1; i<=3; i++) {
01740 sx += matrix.element(1,i)*matrix.element(1,i);
01741 sy += matrix.element(2,i)*matrix.element(2,i);
01742 sz += matrix.element(3,i)*matrix.element(3,i);
01743 }
01744 }
01745 sx = (T)sqrt(sx);
01746 sy = (T)sqrt(sy);
01747 sz = (T)sqrt(sz);
01748 if (!isNormal()) return;
01749
01750 scale.set(sx, sy, sz);
01751
01752
01753 Matrix<T> mt = getRotMatrix();
01754 if (!isInverse) {
01755 for (int i=1; i<=3; i++) {
01756 mt.element(i,1) /= sx;
01757 mt.element(i,2) /= sy;
01758 mt.element(i,3) /= sz;
01759 }
01760 }
01761 else {
01762 for (int i=1; i<=3; i++) {
01763 mt.element(1,i) /= sx;
01764 mt.element(2,i) /= sy;
01765 mt.element(3,i) /= sz;
01766 }
01767 }
01768 rotate = RotMatrix2Quaternion<T>(mt);
01769 mt.free();
01770
01771
01772 if (!isInverse) {
01773 shift.set(matrix.element(1,4), matrix.element(2,4), matrix.element(3,4));
01774 }
01775 else {
01776 Vector<T> sh(matrix.element(1,4)/sx, matrix.element(2,4)/sy, matrix.element(3,4)/sz);
01777 shift = rotate.execInvRotate(sh);
01778 }
01779
01780 return;
01781 }
01782
01783
01784
01785
01786 template <typename T> Vector<T> AffineTrans<T>::execMatrixTrans(Vector<T> v)
01787 {
01788 if (matrix.element(4,4)!=(T)1.0) computeMatrix(true);
01789
01790 Matrix<T> mv(1, 4);
01791 mv.mx[0] = v.x;
01792 mv.mx[1] = v.y;
01793 mv.mx[2] = v.z;
01794 mv.mx[3] = (T)1.0;
01795
01796 Matrix<T> mt = matrix*mv;
01797 Vector<T> vct;
01798 vct.x = mt.mx[0];
01799 vct.y = mt.mx[1];
01800 vct.z = mt.mx[2];
01801
01802 mt.free();
01803 mv.free();
01804
01805 return vct;
01806 }
01807
01808
01809 }
01810
01811
01812 #endif
01813