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_DEFAULTTYPE_VEC_H
00028 #define SOFA_DEFAULTTYPE_VEC_H
00029
00030 #include <sofa/helper/fixed_array.h>
00031 #include <sofa/helper/static_assert.h>
00032 #include <sofa/helper/rmath.h>
00033 #include <functional>
00034
00035
00036 #define EQUALITY_THRESHOLD 1e-6
00037
00038 namespace sofa
00039 {
00040
00041 namespace defaulttype
00042 {
00043
00044 enum NoInit { NOINIT };
00045
00046 template <int N, typename real=float>
00047 class Vec : public helper::fixed_array<real,N>
00048 {
00049 public:
00050
00052 Vec()
00053 {
00054 this->clear();
00055 }
00056
00058 explicit Vec(NoInit)
00059 {
00060 }
00061
00063 explicit Vec(real r1)
00064 {
00065 BOOST_STATIC_ASSERT(N==1);
00066 this->elems[0]=r1;
00067 }
00068
00070 void operator=(real r1)
00071 {
00072 BOOST_STATIC_ASSERT(N == 1);
00073 this->elems[0]=r1;
00074 }
00075
00077 Vec(real r1, real r2)
00078 {
00079 BOOST_STATIC_ASSERT(N == 2);
00080 this->elems[0]=r1;
00081 this->elems[1]=r2;
00082 }
00083
00085 Vec(real r1, real r2, real r3)
00086 {
00087 BOOST_STATIC_ASSERT(N == 3);
00088 this->elems[0]=r1;
00089 this->elems[1]=r2;
00090 this->elems[2]=r3;
00091 }
00092
00094 Vec(real r1, real r2, real r3, real r4)
00095 {
00096 BOOST_STATIC_ASSERT(N == 4);
00097 this->elems[0]=r1;
00098 this->elems[1]=r2;
00099 this->elems[2]=r3;
00100 this->elems[3]=r4;
00101 }
00102
00104 Vec(real r1, real r2, real r3, real r4, real r5, real r6)
00105 {
00106 BOOST_STATIC_ASSERT(N == 6);
00107 this->elems[0]=r1;
00108 this->elems[1]=r2;
00109 this->elems[2]=r3;
00110 this->elems[3]=r4;
00111 this->elems[4]=r5;
00112 this->elems[5]=r6;
00113 }
00114
00116 Vec(real r1, real r2, real r3, real r4, real r5, real r6, real r7, real r8)
00117 {
00118 BOOST_STATIC_ASSERT(N == 8);
00119 this->elems[0]=r1;
00120 this->elems[1]=r2;
00121 this->elems[2]=r3;
00122 this->elems[3]=r4;
00123 this->elems[4]=r5;
00124 this->elems[5]=r6;
00125 this->elems[6]=r7;
00126 this->elems[7]=r8;
00127 }
00128
00130 Vec(real r1, real r2, real r3, real r4, real r5, real r6, real r7, real r8, real r9)
00131 {
00132 BOOST_STATIC_ASSERT(N == 9);
00133 this->elems[0]=r1;
00134 this->elems[1]=r2;
00135 this->elems[2]=r3;
00136 this->elems[3]=r4;
00137 this->elems[4]=r5;
00138 this->elems[5]=r6;
00139 this->elems[6]=r7;
00140 this->elems[7]=r8;
00141 this->elems[8]=r9;
00142 }
00143
00144
00146 Vec(const Vec<N-1,real>& v, real r1)
00147 {
00148 BOOST_STATIC_ASSERT(N > 1);
00149 for(int i=0;i<N-1;i++)
00150 this->elems[i] = v[i];
00151 this->elems[N-1]=r1;
00152 }
00153
00154 template<typename real2>
00155 Vec(const Vec<N, real2>& p)
00156 {
00157
00158 for(int i=0;i<N;i++)
00159 this->elems[i] = (real)p(i);
00160 }
00161
00163 template<typename real2>
00164 explicit Vec(const real2* p)
00165 {
00166
00167 for(int i=0;i<N;i++)
00168 this->elems[i] = (real)p[i];
00169 }
00170
00172 real& x()
00173 {
00174 BOOST_STATIC_ASSERT(N >= 1);
00175 return this->elems[0];
00176 }
00178 real& y()
00179 {
00180 BOOST_STATIC_ASSERT(N >= 2);
00181 return this->elems[1];
00182 }
00184 real& z()
00185 {
00186 BOOST_STATIC_ASSERT(N >= 3);
00187 return this->elems[2];
00188 }
00190 real& w()
00191 {
00192 BOOST_STATIC_ASSERT(N >= 4);
00193 return this->elems[3];
00194 }
00195
00197 const real& x() const
00198 {
00199 BOOST_STATIC_ASSERT(N >= 1);
00200 return this->elems[0];
00201 }
00203 const real& y() const
00204 {
00205 BOOST_STATIC_ASSERT(N >= 2);
00206 return this->elems[1];
00207 }
00209 const real& z() const
00210 {
00211 BOOST_STATIC_ASSERT(N >= 3);
00212 return this->elems[2];
00213 }
00215 const real& w() const
00216 {
00217 BOOST_STATIC_ASSERT(N >= 4);
00218 return this->elems[3];
00219 }
00220
00222 template<typename real2>
00223 void operator=(const real2* p)
00224 {
00225
00226 for(int i=0;i<N;i++)
00227 this->elems[i] = (real)p[i];
00228 }
00229
00231 template<int M, typename real2>
00232 void operator=(const Vec<M,real2>& v)
00233 {
00234
00235 for(int i=0;i<(N>M?M:N);i++)
00236 this->elems[i] = (real)v(i);
00237 }
00238
00240 void clear()
00241 {
00242 this->assign(real());
00243 }
00244
00246 void fill(real r)
00247 {
00248 this->assign(r);
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00261
00262
00263
00264
00265
00267 real& operator()(int i)
00268 {
00269 return this->elems[i];
00270 }
00271
00273 const real& operator()(int i) const
00274 {
00275 return this->elems[i];
00276 }
00277
00280
00281
00282
00283
00284
00287
00288
00289
00290
00291
00293 const real* ptr() const
00294 {
00295 return this->elems;
00296 }
00297
00299 real* ptr()
00300 {
00301 return this->elems;
00302 }
00303
00304
00305
00307 template<class real2>
00308 Vec<N,real> operator*(real2 f) const
00309 {
00310 Vec<N,real> r(NOINIT);
00311 for (int i=0;i<N;i++)
00312 r[i] = this->elems[i]*(real)f;
00313 return r;
00314 }
00315
00317 template<class real2>
00318 void operator*=(real2 f)
00319 {
00320 for (int i=0;i<N;i++)
00321 this->elems[i]*=(real)f;
00322 }
00323
00325 template<class real2>
00326 Vec<N,real> operator/(real2 f) const
00327 {
00328 Vec<N,real> r(NOINIT);
00329 for (int i=0;i<N;i++)
00330 r[i] = this->elems[i]/(real)f;
00331 return r;
00332 }
00333
00335 template<class real2>
00336 void operator/=(real2 f)
00337 {
00338 for (int i=0;i<N;i++)
00339 this->elems[i]/=(real)f;
00340 }
00341
00343 template<class real2>
00344 real operator*(const Vec<N,real2>& v) const
00345 {
00346 real r = (real)(this->elems[0]*v[0]);
00347 for (int i=1;i<N;i++)
00348 r += (real)(this->elems[i]*v[i]);
00349 return r;
00350 }
00351
00353 template<class real2>
00354 Vec<N,real> linearProduct(const Vec<N,real2>& v) const
00355 {
00356 Vec<N,real> r(NOINIT);
00357 for (int i=0;i<N;i++)
00358 r[i]=this->elems[i]*(real)v[i];
00359 return r;
00360 }
00361
00362
00364 template<class real2>
00365 Vec<N,real> linearDivision(const Vec<N,real2>& v) const
00366 {
00367 Vec<N,real> r(NOINIT);
00368 for (int i=0;i<N;i++)
00369 r[i]=this->elems[i]/(real)v[i];
00370 return r;
00371 }
00372
00374 template<class real2>
00375 Vec<N,real> operator+(const Vec<N,real2>& v) const
00376 {
00377 Vec<N,real> r(NOINIT);
00378 for (int i=0;i<N;i++)
00379 r[i]=this->elems[i]+(real)v[i];
00380 return r;
00381 }
00382
00384 template<class real2>
00385 void operator+=(const Vec<N,real2>& v)
00386 {
00387 for (int i=0;i<N;i++)
00388 this->elems[i]+=(real)v[i];
00389 }
00390
00392 template<class real2>
00393 Vec<N,real> operator-(const Vec<N,real2>& v) const
00394 {
00395 Vec<N,real> r(NOINIT);
00396 for (int i=0;i<N;i++)
00397 r[i]=this->elems[i]-(real)v[i];
00398 return r;
00399 }
00400
00402 template<class real2>
00403 void operator-=(const Vec<N,real2>& v)
00404 {
00405 for (int i=0;i<N;i++)
00406 this->elems[i]-=(real)v[i];
00407 }
00408
00410 Vec<N,real> operator-() const
00411 {
00412 Vec<N,real> r(NOINIT);
00413 for (int i=0;i<N;i++)
00414 r[i]=-this->elems[i];
00415 return r;
00416 }
00417
00419 real norm2() const
00420 {
00421 real r = this->elems[0]*this->elems[0];
00422 for (int i=1;i<N;i++)
00423 r += this->elems[i]*this->elems[i];
00424 return r;
00425 }
00426
00428 real norm() const
00429 {
00430 return helper::rsqrt(norm2());
00431 }
00432
00434 void normalize()
00435 {
00436 real r = norm();
00437 if (r>1e-10)
00438 for (int i=0;i<N;i++)
00439 this->elems[i]/=r;
00440 }
00441
00442 Vec cross( const Vec& b ) const
00443 {
00444 BOOST_STATIC_ASSERT(N == 3);
00445 return Vec(
00446 (*this)[1]*b[2] - (*this)[2]*b[1],
00447 (*this)[2]*b[0] - (*this)[0]*b[2],
00448 (*this)[0]*b[1] - (*this)[1]*b[0]
00449 );
00450 }
00451
00452
00454 real sum() const
00455 {
00456 real sum = 0.0;
00457 for (int i=0;i<N;i++)
00458 sum += this->elems[i];
00459 return sum;
00460 }
00461
00462
00465
00466 bool operator==(const Vec& b) const
00467 {
00468 for (int i=0;i<N;i++)
00469 if ( fabs( this->elems[i] - b[i] ) > EQUALITY_THRESHOLD ) return false;
00470 return true;
00471 }
00472
00473 bool operator!=(const Vec& b) const
00474 {
00475 for (int i=0;i<N;i++)
00476 if ( fabs( this->elems[i] - b[i] ) > EQUALITY_THRESHOLD ) return true;
00477 return false;
00478 }
00479
00481 };
00482
00484 template <int N, typename real=float>
00485 class VecNoInit : public Vec<N,real>
00486 {
00487 public:
00488 VecNoInit()
00489 : Vec<N,real>(NOINIT)
00490 {
00491 }
00492
00494 template<typename real2>
00495 void operator=(const real2* p)
00496 {
00497 this->Vec<N,real>::operator=(p);
00498 }
00499
00501 template<int M, typename real2>
00502 void operator=(const Vec<M,real2>& v)
00503 {
00504 this->Vec<N,real>::operator=(v);
00505 }
00506 };
00507
00509 template<int N,typename Real>
00510 std::istream& operator >> ( std::istream& in, Vec<N,Real>& v )
00511 {
00512 for( int i=0; i<N; ++i )
00513 in>>v[i];
00514 return in;
00515 }
00516
00518 template<int N,typename Real>
00519 std::ostream& operator << ( std::ostream& out, const Vec<N,Real>& v )
00520 {
00521 for( int i=0; i<N-1; ++i )
00522 out<<v[i]<<" ";
00523 out<<v[N-1];
00524 return out;
00525 }
00526
00528 template<typename real>
00529 inline Vec<3,real> cross(const Vec<3,real>& a, const Vec<3,real>& b)
00530 {
00531 return Vec<3,real>(a.y()*b.z() - a.z()*b.y(),
00532 a.z()*b.x() - a.x()*b.z(),
00533 a.x()*b.y() - a.y()*b.x());
00534 }
00535
00537 template <typename real>
00538 real cross(const defaulttype::Vec<2,real>& a, const defaulttype::Vec<2,real>& b )
00539 {
00540 return a[0]*b[1] - a[1]*b[0];
00541 }
00542
00544 template<int N,typename real>
00545 inline real dot(const Vec<N,real>& a, const Vec<N,real>& b)
00546 {
00547 return a*b;
00548 }
00549
00550 typedef Vec<1,float> Vec1f;
00551 typedef Vec<1,double> Vec1d;
00552
00553
00554 typedef Vec<2,float> Vec2f;
00555 typedef Vec<2,double> Vec2d;
00556
00557
00558 typedef Vec<3,float> Vec3f;
00559 typedef Vec<3,double> Vec3d;
00560
00561
00562 typedef Vec<4,float> Vec4f;
00563 typedef Vec<4,double> Vec4d;
00564
00565
00566 typedef Vec<6,float> Vec6f;
00567 typedef Vec<6,double> Vec6d;
00568
00569
00570 #ifdef SOFA_FLOAT
00571 typedef Vec1f Vector1;
00572 typedef Vec2f Vector2;
00573 typedef Vec3f Vector3;
00574 typedef Vec4f Vector4;
00575 typedef Vec6f Vector6;
00576 #else
00577 typedef Vec1d Vector1;
00578 typedef Vec2d Vector2;
00579 typedef Vec3d Vector3;
00580 typedef Vec4d Vector4;
00581 typedef Vec6d Vector6;
00582 #endif
00583 }
00584
00585 }
00586
00588 template <int N, typename real>
00589 sofa::defaulttype::Vec<N,real> operator*(real r, const sofa::defaulttype::Vec<N,real>& v)
00590 {
00591 return v*r;
00592 }
00593
00594
00595
00596 namespace std
00597 {
00598
00599
00600 template<int N, class T>
00601 struct less< sofa::defaulttype::Vec<N,T> > : public binary_function< sofa::defaulttype::Vec<N,T>, sofa::defaulttype::Vec<N,T>, bool>
00602 {
00603 bool operator()(const sofa::defaulttype::Vec<N,T>& x, const sofa::defaulttype::Vec<N,T>& y) const
00604 {
00605
00606 for( unsigned i=0; i<N; ++i ) {
00607 if( x[i]<y[i] )
00608 return true;
00609 else if( y[i]<x[i] )
00610 return false;
00611 }
00612 return false;
00613 }
00614 };
00615
00616 }
00617
00618 #endif
00619