Quater.inl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef SOFA_HELPER_QUATER_INL
00028 #define SOFA_HELPER_QUATER_INL
00029
00030 #include "Quater.h"
00031 #include <cstdio>
00032 #include <math.h>
00033 #include <iostream>
00034
00035 namespace sofa
00036 {
00037
00038 namespace helper
00039 {
00040
00041 #define RENORMCOUNT 50
00042
00043
00044 template<class Real>
00045 Quater<Real>::Quater()
00046 {
00047 _q[0] = _q[1] = _q[2] = _q[3] = 0.0;
00048 }
00049
00050 template<class Real>
00051 Quater<Real>::Quater(Real x, Real y, Real z, Real w)
00052 {
00053 _q[0] = x;
00054 _q[1] = y;
00055 _q[2] = z;
00056 _q[3] = w;
00057 }
00058
00059 template<class Real>
00060 Quater<Real>::Quater( const defaulttype::Vec<3,Real>& axis, Real angle )
00061 {
00062 axisToQuat(axis,angle);
00063 }
00064
00065
00066 template<class Real>
00067 Quater<Real>::~Quater()
00068 {
00069 }
00070
00077 template<class Real>
00078
00079 Quater<Real> Quater<Real>::operator+(const Quater<Real> &q1) const
00080 {
00081 static int count = 0;
00082
00083 Real t1[4], t2[4], t3[4];
00084 Real tf[4];
00085 Quater<Real> ret;
00086
00087 t1[0] = _q[0] * q1._q[3];
00088 t1[1] = _q[1] * q1._q[3];
00089 t1[2] = _q[2] * q1._q[3];
00090
00091 t2[0] = q1._q[0] * _q[3];
00092 t2[1] = q1._q[1] * _q[3];
00093 t2[2] = q1._q[2] * _q[3];
00094
00095
00096 t3[0] = (q1._q[1] * _q[2]) - (q1._q[2] * _q[1]);
00097 t3[1] = (q1._q[2] * _q[0]) - (q1._q[0] * _q[2]);
00098 t3[2] = (q1._q[0] * _q[1]) - (q1._q[1] * _q[0]);
00099
00100
00101 tf[0] = t1[0] + t2[0] + t3[0];
00102 tf[1] = t1[1] + t2[1] + t3[1];
00103 tf[2] = t1[2] + t2[2] + t3[2];
00104 tf[3] = _q[3] * q1._q[3] -
00105 (_q[0] * q1._q[0] + _q[1] * q1._q[1] + _q[2] * q1._q[2]);
00106
00107 ret._q[0] = tf[0];
00108 ret._q[1] = tf[1];
00109 ret._q[2] = tf[2];
00110 ret._q[3] = tf[3];
00111
00112 if (++count > RENORMCOUNT)
00113 {
00114 count = 0;
00115 ret.normalize();
00116 }
00117
00118 return ret;
00119 }
00120
00121 template<class Real>
00122
00123 Quater<Real> Quater<Real>::operator*(const Quater<Real>& q1) const
00124 {
00125 Quater<Real> ret;
00126
00127 ret._q[3] = _q[3] * q1._q[3] -
00128 (_q[0] * q1._q[0] +
00129 _q[1] * q1._q[1] +
00130 _q[2] * q1._q[2]);
00131 ret._q[0] = _q[3] * q1._q[0] +
00132 _q[0] * q1._q[3] +
00133 _q[1] * q1._q[2] -
00134 _q[2] * q1._q[1];
00135 ret._q[1] = _q[3] * q1._q[1] +
00136 _q[1] * q1._q[3] +
00137 _q[2] * q1._q[0] -
00138 _q[0] * q1._q[2];
00139 ret._q[2] = _q[3] * q1._q[2] +
00140 _q[2] * q1._q[3] +
00141 _q[0] * q1._q[1] -
00142 _q[1] * q1._q[0];
00143
00144 return ret;
00145 }
00146
00147 template<class Real>
00148 Quater<Real> Quater<Real>::operator*(const Real& r) const
00149 {
00150 Quater<Real> ret;
00151 ret[0] = _q[0] * r;
00152 ret[1] = _q[1] * r;
00153 ret[2] = _q[2] * r;
00154 ret[3] = _q[3] * r;
00155 return ret;
00156 }
00157
00158 template<class Real>
00159 Quater<Real> Quater<Real>::quatVectMult(const defaulttype::Vec<3,Real>& vect)
00160 {
00161 Quater<Real> ret;
00162
00163 ret._q[3] = (Real) (-(_q[0] * vect[0] + _q[1] * vect[1] + _q[2] * vect[2]));
00164 ret._q[0] = (Real) (_q[3] * vect[0] + _q[1] * vect[2] - _q[2] * vect[1]);
00165 ret._q[1] = (Real) (_q[3] * vect[1] + _q[2] * vect[0] - _q[0] * vect[2]);
00166 ret._q[2] = (Real) (_q[3] * vect[2] + _q[0] * vect[1] - _q[1] * vect[0]);
00167
00168 return ret;
00169 }
00170
00171 template<class Real>
00172 Quater<Real> Quater<Real>::vectQuatMult(const defaulttype::Vec<3,Real>& vect)
00173 {
00174 Quater<Real> ret;
00175
00176 ret[3] = (Real) (-(vect[0] * _q[0] + vect[1] * _q[1] + vect[2] * _q[2]));
00177 ret[0] = (Real) (vect[0] * _q[3] + vect[1] * _q[2] - vect[2] * _q[1]);
00178 ret[1] = (Real) (vect[1] * _q[3] + vect[2] * _q[0] - vect[0] * _q[2]);
00179 ret[2] = (Real) (vect[2] * _q[3] + vect[0] * _q[1] - vect[1] * _q[0]);
00180
00181 return ret;
00182 }
00183
00184 template<class Real>
00185 Quater<Real> Quater<Real>::inverse() const
00186 {
00187 Quater<Real> ret;
00188
00189 Real norm = sqrt(_q[0] * _q[0] +
00190 _q[1] * _q[1] +
00191 _q[2] * _q[2] +
00192 _q[3] * _q[3]);
00193
00194 if (norm != 0.0f)
00195 {
00196 norm = 1.0f / norm;
00197 ret._q[3] = _q[3] * norm;
00198 for (int i = 0; i < 3; i++)
00199 {
00200 ret._q[i] = -_q[i] * norm;
00201 }
00202 }
00203 else
00204 {
00205 for (int i = 0; i < 4; i++)
00206 {
00207 ret._q[i] = 0.0;
00208 }
00209 }
00210
00211 return ret;
00212 }
00213
00217 template<class Real>
00218 void Quater<Real>::normalize()
00219 {
00220 int i;
00221 Real mag;
00222
00223 mag = (_q[0] * _q[0] + _q[1] * _q[1] + _q[2] * _q[2] + _q[3] * _q[3]);
00224 if( mag != 0)
00225 {
00226 for (i = 0; i < 4; i++)
00227 {
00228 _q[i] /= sqrt(mag);
00229 }
00230 }
00231 }
00232
00233 template<class Real>
00234 void Quater<Real>::fromMatrix(const defaulttype::Matrix3 &m)
00235 {
00236 Real tr, s;
00237
00238 tr = (Real)(m.x().x() + m.y().y() + m.z().z());
00239
00240
00241 if (tr > 0)
00242 {
00243 s = (float)sqrt (tr + 1);
00244 _q[3] = s * 0.5f;
00245 s = 0.5f / s;
00246 _q[0] = (Real)((m.z().y() - m.y().z()) * s);
00247 _q[1] = (Real)((m.x().z() - m.z().x()) * s);
00248 _q[2] = (Real)((m.y().x() - m.x().y()) * s);
00249 }
00250 else
00251 {
00252 if (m.y().y() > m.x().x() && m.z().z() <= m.y().y())
00253 {
00254 s = (Real)sqrt ((m.y().y() - (m.z().z() + m.x().x())) + 1.0f);
00255
00256 _q[1] = s * 0.5f;
00257
00258 if (s != 0.0f)
00259 s = 0.5f / s;
00260
00261 _q[2] = (Real)((m.y().z() + m.z().y()) * s);
00262 _q[0] = (Real)((m.x().y() + m.y().x()) * s);
00263 _q[3] = (Real)((m.x().z() - m.z().x()) * s);
00264 }
00265 else if ((m.y().y() <= m.x().x() && m.z().z() > m.x().x()) || (m.z().z() > m.y().y()))
00266 {
00267 s = (Real)sqrt ((m.z().z() - (m.x().x() + m.y().y())) + 1.0f);
00268
00269 _q[2] = s * 0.5f;
00270
00271 if (s != 0.0f)
00272 s = 0.5f / s;
00273
00274 _q[0] = (Real)((m.z().x() + m.x().z()) * s);
00275 _q[1] = (Real)((m.y().z() + m.z().y()) * s);
00276 _q[3] = (Real)((m.y().x() - m.x().y()) * s);
00277 }
00278 else
00279 {
00280 s = (Real)sqrt ((m.x().x() - (m.y().y() + m.z().z())) + 1.0f);
00281
00282 _q[0] = s * 0.5f;
00283
00284 if (s != 0.0f)
00285 s = 0.5f / s;
00286
00287 _q[1] = (Real)((m.x().y() + m.y().x()) * s);
00288 _q[2] = (Real)((m.z().x() + m.x().z()) * s);
00289 _q[3] = (Real)((m.z().y() - m.y().z()) * s);
00290 }
00291 }
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00311 template<class Real>
00312 void Quater<Real>::buildRotationMatrix(Real m[4][4]) const
00313 {
00314 m[0][0] = (1.0f - 2.0f * (_q[1] * _q[1] + _q[2] * _q[2]));
00315 m[0][1] = (2.0f * (_q[0] * _q[1] - _q[2] * _q[3]));
00316 m[0][2] = (2.0f * (_q[2] * _q[0] + _q[1] * _q[3]));
00317 m[0][3] = 0;
00318
00319 m[1][0] = (2.0f * (_q[0] * _q[1] + _q[2] * _q[3]));
00320 m[1][1] = (1.0f - 2.0f * (_q[2] * _q[2] + _q[0] * _q[0]));
00321 m[1][2] = (2.0f * (_q[1] * _q[2] - _q[0] * _q[3]));
00322 m[1][3] = 0;
00323
00324 m[2][0] = (2.0f * (_q[2] * _q[0] - _q[1] * _q[3]));
00325 m[2][1] = (2.0f * (_q[1] * _q[2] + _q[0] * _q[3]));
00326 m[2][2] = (1.0f - 2.0f * (_q[1] * _q[1] + _q[0] * _q[0]));
00327 m[2][3] = 0;
00328
00329 m[3][0] = 0;
00330 m[3][1] = 0;
00331 m[3][2] = 0;
00332 m[3][3] = 1;
00333 }
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00360 template<class Real>
00361 void Quater<Real>::writeOpenGlMatrix(double *m) const
00362 {
00363 m[0*4+0] = (1.0f - 2.0f * (_q[1] * _q[1] + _q[2] * _q[2]));
00364 m[1*4+0] = (2.0f * (_q[0] * _q[1] - _q[2] * _q[3]));
00365 m[2*4+0] = (2.0f * (_q[2] * _q[0] + _q[1] * _q[3]));
00366 m[3*4+0] = 0.0f;
00367
00368 m[0*4+1] = (2.0f * (_q[0] * _q[1] + _q[2] * _q[3]));
00369 m[1*4+1] = (1.0f - 2.0f * (_q[2] * _q[2] + _q[0] * _q[0]));
00370 m[2*4+1] = (float) (2.0f * (_q[1] * _q[2] - _q[0] * _q[3]));
00371 m[3*4+1] = 0.0f;
00372
00373 m[0*4+2] = (float) (2.0f * (_q[2] * _q[0] - _q[1] * _q[3]));
00374 m[1*4+2] = (float) (2.0f * (_q[1] * _q[2] + _q[0] * _q[3]));
00375 m[2*4+2] = (float) (1.0f - 2.0f * (_q[1] * _q[1] + _q[0] * _q[0]));
00376 m[3*4+2] = 0.0f;
00377
00378 m[0*4+3] = 0.0f;
00379 m[1*4+3] = 0.0f;
00380 m[2*4+3] = 0.0f;
00381 m[3*4+3] = 1.0f;
00382 }
00383
00385 template<class Real>
00386 void Quater<Real>::writeOpenGlMatrix(float *m) const
00387 {
00388 m[0*4+0] = (float) (1.0f - 2.0f * (_q[1] * _q[1] + _q[2] * _q[2]));
00389 m[1*4+0] = (float) (2.0f * (_q[0] * _q[1] - _q[2] * _q[3]));
00390 m[2*4+0] = (float) (2.0f * (_q[2] * _q[0] + _q[1] * _q[3]));
00391 m[3*4+0] = 0.0f;
00392
00393 m[0*4+1] = (float) (2.0f * (_q[0] * _q[1] + _q[2] * _q[3]));
00394 m[1*4+1] = (float) (1.0f - 2.0f * (_q[2] * _q[2] + _q[0] * _q[0]));
00395 m[2*4+1] = (float) (2.0f * (_q[1] * _q[2] - _q[0] * _q[3]));
00396 m[3*4+1] = 0.0f;
00397
00398 m[0*4+2] = (float) (2.0f * (_q[2] * _q[0] - _q[1] * _q[3]));
00399 m[1*4+2] = (float) (2.0f * (_q[1] * _q[2] + _q[0] * _q[3]));
00400 m[2*4+2] = (float) (1.0f - 2.0f * (_q[1] * _q[1] + _q[0] * _q[0]));
00401 m[3*4+2] = 0.0f;
00402
00403 m[0*4+3] = 0.0f;
00404 m[1*4+3] = 0.0f;
00405 m[2*4+3] = 0.0f;
00406 m[3*4+3] = 1.0f;
00407 }
00408
00410 template<class Real>
00411 Quater<Real> Quater<Real>::axisToQuat(defaulttype::Vec<3,Real> a, Real phi)
00412 {
00413 a = a / a.norm();
00414 _q[0] = (Real)a.x();
00415 _q[1] = (Real)a.y();
00416 _q[2] = (Real)a.z();
00417
00418 _q[0] = _q[0] * (Real)sin(phi / 2.0);
00419 _q[1] = _q[1] * (Real)sin(phi / 2.0);
00420 _q[2] = _q[2] * (Real)sin(phi / 2.0);
00421
00422 _q[3] = (Real)cos(phi / 2.0);
00423
00424 return *this;
00425 }
00426
00427 template<class Real>
00428 defaulttype::Vec<3,Real> Quater<Real>::toEulerVector() const
00429 {
00430 Quater<Real> q = *this;
00431 q.normalize();
00432
00433 double angle = acos(q._q[3]) * 2;
00434
00435 defaulttype::Vec<3,Real> v(q._q[0], q._q[1], q._q[2]);
00436
00437 double norm = sqrt( (double) (v.x() * v.x() + v.y() * v.y() + v.z() * v.z()) );
00438 if (norm > 0.0005){
00439 v /= norm;
00440 v *= angle;
00441 }
00442
00443 return v;
00444 }
00445
00447
00448
00449
00450
00451
00452
00453
00455 template<class Real>
00456 void Quater<Real>::print()
00457 {
00458 printf("(%f, %f ,%f, %f)\n", _q[0], _q[1], _q[2], _q[3]);
00459 }
00460
00461 template<class Real>
00462 void Quater<Real>::operator+=(const Quater<Real>& q2)
00463 {
00464 static int count = 0;
00465
00466 Real t1[4], t2[4], t3[4];
00467 Quater<Real> q1 = (*this);
00468 t1[0] = q1._q[0] * q2._q[3];
00469 t1[1] = q1._q[1] * q2._q[3];
00470 t1[2] = q1._q[2] * q2._q[3];
00471
00472 t2[0] = q2._q[0] * q1._q[3];
00473 t2[1] = q2._q[1] * q1._q[3];
00474 t2[2] = q2._q[2] * q1._q[3];
00475
00476
00477 t3[0] = (q2._q[1] * q1._q[2]) - (q2._q[2] * q1._q[1]);
00478 t3[1] = (q2._q[2] * q1._q[0]) - (q2._q[0] * q1._q[2]);
00479 t3[2] = (q2._q[0] * q1._q[1]) - (q2._q[1] * q1._q[0]);
00480
00481
00482 _q[0] = t1[0] + t2[0] + t3[0];
00483 _q[1] = t1[1] + t2[1] + t3[1];
00484 _q[2] = t1[2] + t2[2] + t3[2];
00485 _q[3] = q1._q[3] * q2._q[3] -
00486 (q1._q[0] * q2._q[0] + q1._q[1] * q2._q[1] + q1._q[2] * q2._q[2]);
00487
00488 if (++count > RENORMCOUNT)
00489 {
00490 count = 0;
00491 normalize();
00492 }
00493 }
00494
00495 template<class Real>
00496 void Quater<Real>::operator*=(const Quater<Real>& q1)
00497 {
00498 Quater<Real> q2 = *this;
00499 _q[3] = q2._q[3] * q1._q[3] -
00500 (q2._q[0] * q1._q[0] +
00501 q2._q[1] * q1._q[1] +
00502 q2._q[2] * q1._q[2]);
00503 _q[0] = q2._q[3] * q1._q[0] +
00504 q2._q[0] * q1._q[3] +
00505 q2._q[1] * q1._q[2] -
00506 q2._q[2] * q1._q[1];
00507 _q[1] = q2._q[3] * q1._q[1] +
00508 q2._q[1] * q1._q[3] +
00509 q2._q[2] * q1._q[0] -
00510 q2._q[0] * q1._q[2];
00511 _q[2] = q2._q[3] * q1._q[2] +
00512 q2._q[2] * q1._q[3] +
00513 q2._q[0] * q1._q[1] -
00514 q2._q[1] * q1._q[0];
00515 }
00516
00517
00518 }
00519
00520 }
00521
00522 #endif