Quater.h
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_H
00028 #define SOFA_HELPER_QUATER_H
00029
00030 #include <sofa/defaulttype/Vec.h>
00031 #include <sofa/defaulttype/Mat.h>
00032 #include <math.h>
00033 #include <assert.h>
00034 #include <iostream>
00035
00036 namespace sofa
00037 {
00038
00039 namespace helper
00040 {
00041
00042 template<class Real>
00043 class Quater
00044 {
00045 private:
00046 Real _q[4];
00047
00048 public:
00049 Quater();
00050 virtual ~Quater();
00051 Quater(Real x, Real y, Real z, Real w);
00052 template<class Real2>
00053 Quater(const Real2 q[]) { for (int i=0; i<4; i++) _q[i] = (Real)q[i]; }
00054 template<class Real2>
00055 Quater(const Quater<Real2>& q) { for (int i=0; i<4; i++) _q[i] = (Real)q[i]; }
00056 Quater( const defaulttype::Vec<3,Real>& axis, Real angle );
00057
00058 static Quater identity() {
00059 return Quater(0,0,0,1);
00060 }
00061
00062
00064 const Real* ptr() const
00065 {
00066 return this->_q;
00067 }
00068
00070 Real* ptr()
00071 {
00072 return this->_q;
00073 }
00074
00076 void normalize();
00077
00078 void clear()
00079 {
00080 _q[0]=0.0;
00081 _q[1]=0.0;
00082 _q[2]=0.0;
00083 _q[3]=1.0;
00084 }
00085
00086 void fromMatrix(const defaulttype::Matrix3 &m);
00087
00088 template<class Mat33>
00089 void toMatrix(Mat33 &m) const
00090 {
00091 m[0][0] = (typename Mat33::Real) (1.0f - 2.0f * (_q[1] * _q[1] + _q[2] * _q[2]));
00092 m[0][1] = (typename Mat33::Real) (2.0f * (_q[0] * _q[1] - _q[2] * _q[3]));
00093 m[0][2] = (typename Mat33::Real) (2.0f * (_q[2] * _q[0] + _q[1] * _q[3]));
00094
00095 m[1][0] = (typename Mat33::Real) (2.0f * (_q[0] * _q[1] + _q[2] * _q[3]));
00096 m[1][1] = (typename Mat33::Real) (1.0f - 2.0f * (_q[2] * _q[2] + _q[0] * _q[0]));
00097 m[1][2] = (typename Mat33::Real) (2.0f * (_q[1] * _q[2] - _q[0] * _q[3]));
00098
00099 m[2][0] = (typename Mat33::Real) (2.0f * (_q[2] * _q[0] - _q[1] * _q[3]));
00100 m[2][1] = (typename Mat33::Real) (2.0f * (_q[1] * _q[2] + _q[0] * _q[3]));
00101 m[2][2] = (typename Mat33::Real) (1.0f - 2.0f * (_q[1] * _q[1] + _q[0] * _q[0]));
00102 }
00103
00105 template<class Vec>
00106 Vec rotate( const Vec& v ) const
00107 {
00108 return Vec(
00109 (typename Vec::value_type)((1.0f - 2.0f * (_q[1] * _q[1] + _q[2] * _q[2]))*v[0] + (2.0f * (_q[0] * _q[1] - _q[2] * _q[3])) * v[1] + (2.0f * (_q[2] * _q[0] + _q[1] * _q[3])) * v[2]),
00110 (typename Vec::value_type)((2.0f * (_q[0] * _q[1] + _q[2] * _q[3]))*v[0] + (1.0f - 2.0f * (_q[2] * _q[2] + _q[0] * _q[0]))*v[1] + (2.0f * (_q[1] * _q[2] - _q[0] * _q[3]))*v[2]),
00111 (typename Vec::value_type)((2.0f * (_q[2] * _q[0] - _q[1] * _q[3]))*v[0] + (2.0f * (_q[1] * _q[2] + _q[0] * _q[3]))*v[1] + (1.0f - 2.0f * (_q[1] * _q[1] + _q[0] * _q[0]))*v[2])
00112 );
00113
00114 }
00115
00117 template<class Vec>
00118 Vec inverseRotate( const Vec& v ) const
00119 {
00120 return Vec(
00121 (typename Vec::value_type)((1.0f - 2.0f * (_q[1] * _q[1] + _q[2] * _q[2]))*v[0] + (2.0f * (_q[0] * _q[1] + _q[2] * _q[3])) * v[1] + (2.0f * (_q[2] * _q[0] - _q[1] * _q[3])) * v[2]),
00122 (typename Vec::value_type)((2.0f * (_q[0] * _q[1] - _q[2] * _q[3]))*v[0] + (1.0f - 2.0f * (_q[2] * _q[2] + _q[0] * _q[0]))*v[1] + (2.0f * (_q[1] * _q[2] + _q[0] * _q[3]))*v[2]),
00123 (typename Vec::value_type)((2.0f * (_q[2] * _q[0] + _q[1] * _q[3]))*v[0] + (2.0f * (_q[1] * _q[2] - _q[0] * _q[3]))*v[1] + (1.0f - 2.0f * (_q[1] * _q[1] + _q[0] * _q[0]))*v[2])
00124 );
00125
00126 }
00127
00131
00132
00133 Quater<Real> operator+(const Quater<Real> &q1) const;
00134
00135 Quater<Real> operator*(const Quater<Real> &q1) const;
00136
00137 Quater<Real> operator*(const Real &r) const;
00138
00140
00141
00142
00143 Quater quatVectMult(const defaulttype::Vec<3,Real>& vect);
00144
00145 Quater vectQuatMult(const defaulttype::Vec<3,Real>& vect);
00146
00147 Real& operator[](int index)
00148 {
00149 assert(index >= 0 && index < 4);
00150 return _q[index];
00151 }
00152
00153 const Real& operator[](int index) const
00154 {
00155 assert(index >= 0 && index < 4);
00156 return _q[index];
00157 }
00158
00159 Quater inverse() const;
00160
00161 defaulttype::Vec<3,Real> toEulerVector() const;
00162
00163
00164
00165
00166 void buildRotationMatrix(Real m[4][4]) const;
00167 void writeOpenGlMatrix( double* m ) const;
00168 void writeOpenGlMatrix( float* m ) const;
00169
00170
00171
00172
00173
00174
00175
00176
00177 Quater axisToQuat(defaulttype::Vec<3,Real> a, Real phi);
00178
00180 template<class V>
00181 static Quater createFromRotationVector(const V& a)
00182 {
00183 Real phi = (Real)sqrt(a*a);
00184 if( phi < 1.0e-5 )
00185 return Quater(0,0,0,1);
00186 else {
00187 Real nor = 1/phi;
00188 Real s = (Real)sin(phi/2);
00189 return Quater( a[0]*s*nor, a[1]*s*nor,a[2]*s*nor, (Real)cos(phi/2) );
00190 }
00191 }
00192
00194 static Quater createQuaterFromEuler( defaulttype::Vec<3,Real> v) {
00195 Real quat[4]; Real a0 = v.elems[0];
00196 Real a1 = v.elems[1];
00197 Real a2 = v.elems[2];
00198 quat[3] = cos(a0/2)*cos(a1/2)*cos(a2/2) + sin(a0/2)*sin(a1/2)*sin(a2/2);
00199 quat[0] = sin(a0/2)*cos(a1/2)*cos(a2/2) - cos(a0/2)*sin(a1/2)*sin(a2/2);
00200 quat[1] = cos(a0/2)*sin(a1/2)*cos(a2/2) + sin(a0/2)*cos(a1/2)*sin(a2/2);
00201 quat[2] = cos(a0/2)*cos(a1/2)*sin(a2/2) - sin(a0/2)*sin(a1/2)*cos(a2/2);
00202 Quater quatResult( quat[0], quat[1], quat[2], quat[3] );
00203 return quatResult;
00204 }
00205
00207 template<class T>
00208 static Quater createFromRotationVector(T a0, T a1, T a2 )
00209 {
00210 Real phi = (Real)sqrt((Real)(a0*a0+a1*a1+a2*a2));
00211 if( phi < 1.0e-5 )
00212 return Quater(0,0,0,1);
00213 else {
00214 Real nor = 1/phi;
00215 Real s = (Real)sin(phi/2.0);
00216 return Quater( a0*s*nor, a1*s*nor,a2*s*nor, (Real)cos(phi/2.0) );
00217 }
00218 }
00220 template<class V>
00221 static Quater set(const V& a){ return createFromRotationVector(a); }
00222
00224 template<class T>
00225 static Quater set(T a0, T a1, T a2){ return createFromRotationVector(a0,a1,a2); }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 void print();
00237
00238 void operator+=(const Quater& q2);
00239 void operator*=(const Quater& q2);
00240
00242 inline friend std::ostream& operator << ( std::ostream& out, const Quater& v ){
00243 out<<v._q[0]<<" "<<v._q[1]<<" "<<v._q[2]<<" "<<v._q[3];
00244 return out;
00245 }
00247 inline friend std::istream& operator >> ( std::istream& in, Quater& v ){
00248 in>>v._q[0]>>v._q[1]>>v._q[2]>>v._q[3];
00249 return in;
00250 }
00251
00252 static unsigned int size(){return 4;};
00253 };
00254
00255
00256
00257
00258
00259 }
00260
00261 }
00262
00263 #endif
00264