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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #ifdef DOXYGEN
00046
00047
00048 #define OPENMESH_VECTOR_HH
00049
00050 #define DIM N
00051 #define TEMPLATE_HEADER template <typename Scalar, int N>
00052 #define CLASSNAME VectorT
00053 #define DERIVED VectorDataT<Scalar,N>
00054 #define unroll(expr) for (int i=0; i<N; ++i) expr(i)
00055
00056 #endif
00057
00058 #if defined( OPENMESH_VECTOR_HH )
00059
00060
00061
00062 TEMPLATE_HEADER
00063 class CLASSNAME : public DERIVED
00064 {
00065 private:
00066 typedef DERIVED Base;
00067 public:
00068
00069
00070
00072 typedef Scalar value_type;
00073
00075 typedef VectorT<Scalar,DIM> vector_type;
00076
00078 static inline int dim() { return DIM; }
00079
00081 static inline size_t size() { return DIM; }
00082
00083 static const size_t size_ = DIM;
00084
00085
00086
00087
00089 inline VectorT() {}
00090
00092 explicit inline VectorT(const Scalar& v) {
00093
00094
00095 vectorize(v);
00096 }
00097
00099 inline VectorT(const Scalar& v0, const Scalar& v1) {
00100 assert(DIM==2);
00101 Base::values_[0] = v0; Base::values_[1] = v1;
00102 }
00103
00105 inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2) {
00106 assert(DIM==3);
00107 Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2;
00108 }
00109
00111 inline VectorT(const Scalar& v0, const Scalar& v1,
00112 const Scalar& v2, const Scalar& v3) {
00113 assert(DIM==4);
00114 Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; Base::values_[3]=v3;
00115 }
00116
00118 inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2,
00119 const Scalar& v3, const Scalar& v4) {
00120 assert(DIM==5);
00121 Base::values_[0]=v0; Base::values_[1]=v1;Base::values_[2]=v2; Base::values_[3]=v3; Base::values_[4]=v4;
00122 }
00123
00125 inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2,
00126 const Scalar& v3, const Scalar& v4, const Scalar& v5) {
00127 assert(DIM==6);
00128 Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2;
00129 Base::values_[3]=v3; Base::values_[4]=v4; Base::values_[5]=v5;
00130 }
00131
00133 explicit inline VectorT(const Scalar _values[DIM]) {
00134 memcpy(Base::values_, _values, DIM*sizeof(Scalar));
00135 }
00136
00137
00138 #ifdef OM_CC_MIPS
00139
00140
00141 inline vector_type& operator=(const vector_type& _rhs) {
00142 memcpy(Base::values_, _rhs.Base::values_, DIM*sizeof(Scalar));
00143 return *this;
00144 }
00145 #endif
00146
00147
00149 template<typename otherScalarType>
00150 explicit inline VectorT(const VectorT<otherScalarType,DIM>& _rhs) {
00151 operator=(_rhs);
00152 }
00153
00154
00155
00156
00157
00158
00160 template<typename otherScalarType>
00161 inline vector_type& operator=(const VectorT<otherScalarType,DIM>& _rhs) {
00162 #define expr(i) Base::values_[i] = (Scalar)_rhs[i];
00163 unroll(expr);
00164 #undef expr
00165 return *this;
00166 }
00167
00168
00169
00170
00171
00172
00173
00175 inline Scalar* data() { return Base::values_; }
00176
00178 inline const Scalar*data() const { return Base::values_; }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00196 inline Scalar& operator[](size_t _i) {
00197 assert(_i<DIM); return Base::values_[_i];
00198 }
00199
00201 inline const Scalar& operator[](size_t _i) const {
00202 assert(_i<DIM); return Base::values_[_i];
00203 }
00204
00205
00206
00207
00208
00209
00211 inline bool operator==(const vector_type& _rhs) const {
00212 #define expr(i) if(Base::values_[i]!=_rhs.Base::values_[i]) return false;
00213 unroll(expr);
00214 #undef expr
00215 return true;
00216 }
00217
00219 inline bool operator!=(const vector_type& _rhs) const {
00220 return !(*this == _rhs);
00221 }
00222
00223
00224
00225
00226
00227
00229 inline vector_type& operator*=(const Scalar& _s) {
00230 #define expr(i) Base::values_[i] *= _s;
00231 unroll(expr);
00232 #undef expr
00233 return *this;
00234 }
00235
00238 inline vector_type& operator/=(const Scalar& _s) {
00239 #define expr(i) Base::values_[i] /= _s;
00240 unroll(expr);
00241 #undef expr
00242 return *this;
00243 }
00244
00245
00247 inline vector_type operator*(const Scalar& _s) const {
00248 #if DIM==N
00249 return vector_type(*this) *= _s;
00250 #else
00251 #define expr(i) Base::values_[i] * _s
00252 return vector_type(unroll_csv(expr));
00253 #undef expr
00254 #endif
00255 }
00256
00257
00259 inline vector_type operator/(const Scalar& _s) const {
00260 #if DIM==N
00261 return vector_type(*this) /= _s;
00262 #else
00263 #define expr(i) Base::values_[i] / _s
00264 return vector_type(unroll_csv(expr));
00265 #undef expr
00266 #endif
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00277 inline vector_type& operator*=(const vector_type& _rhs) {
00278 #define expr(i) Base::values_[i] *= _rhs[i];
00279 unroll(expr);
00280 #undef expr
00281 return *this;
00282 }
00283
00285 inline vector_type& operator/=(const vector_type& _rhs) {
00286 #define expr(i) Base::values_[i] /= _rhs[i];
00287 unroll(expr);
00288 #undef expr
00289 return *this;
00290 }
00291
00293 inline vector_type& operator-=(const vector_type& _rhs) {
00294 #define expr(i) Base::values_[i] -= _rhs[i];
00295 unroll(expr);
00296 #undef expr
00297 return *this;
00298 }
00299
00301 inline vector_type& operator+=(const vector_type& _rhs) {
00302 #define expr(i) Base::values_[i] += _rhs[i];
00303 unroll(expr);
00304 #undef expr
00305 return *this;
00306 }
00307
00308
00310 inline vector_type operator*(const vector_type& _v) const {
00311 #if DIM==N
00312 return vector_type(*this) *= _v;
00313 #else
00314 #define expr(i) Base::values_[i] * _v.Base::values_[i]
00315 return vector_type(unroll_csv(expr));
00316 #undef expr
00317 #endif
00318 }
00319
00320
00322 inline vector_type operator/(const vector_type& _v) const {
00323 #if DIM==N
00324 return vector_type(*this) /= _v;
00325 #else
00326 #define expr(i) Base::values_[i] / _v.Base::values_[i]
00327 return vector_type(unroll_csv(expr));
00328 #undef expr
00329 #endif
00330 }
00331
00332
00334 inline vector_type operator+(const vector_type& _v) const {
00335 #if DIM==N
00336 return vector_type(*this) += _v;
00337 #else
00338 #define expr(i) Base::values_[i] + _v.Base::values_[i]
00339 return vector_type(unroll_csv(expr));
00340 #undef expr
00341 #endif
00342 }
00343
00344
00346 inline vector_type operator-(const vector_type& _v) const {
00347 #if DIM==N
00348 return vector_type(*this) -= _v;
00349 #else
00350 #define expr(i) Base::values_[i] - _v.Base::values_[i]
00351 return vector_type(unroll_csv(expr));
00352 #undef expr
00353 #endif
00354 }
00355
00356
00358 inline vector_type operator-(void) const {
00359 vector_type v;
00360 #define expr(i) v.Base::values_[i] = -Base::values_[i];
00361 unroll(expr);
00362 #undef expr
00363 return v;
00364 }
00365
00366
00369 inline VectorT<Scalar,3> operator%(const VectorT<Scalar,3>& _rhs) const
00370 #if DIM==3
00371 {
00372 return
00373 VectorT<Scalar,3>(Base::values_[1]*_rhs.Base::values_[2]-Base::values_[2]*_rhs.Base::values_[1],
00374 Base::values_[2]*_rhs.Base::values_[0]-Base::values_[0]*_rhs.Base::values_[2],
00375 Base::values_[0]*_rhs.Base::values_[1]-Base::values_[1]*_rhs.Base::values_[0]);
00376 }
00377 #else
00378 ;
00379 #endif
00380
00381
00384 inline Scalar operator|(const vector_type& _rhs) const {
00385 Scalar p(0);
00386 #define expr(i) p += Base::values_[i] * _rhs.Base::values_[i];
00387 unroll(expr);
00388 #undef expr
00389 return p;
00390 }
00391
00392
00393
00394
00395
00396
00397
00399
00400
00401 inline Scalar norm() const { return (Scalar)sqrt(sqrnorm()); }
00402 inline Scalar length() const { return norm(); }
00403
00405 inline Scalar sqrnorm() const
00406 {
00407 #if DIM==N
00408 Scalar s(0);
00409 #define expr(i) s += Base::values_[i] * Base::values_[i];
00410 unroll(expr);
00411 #undef expr
00412 return s;
00413 #else
00414 #define expr(i) Base::values_[i]*Base::values_[i]
00415 return (unroll_comb(expr, +));
00416 #undef expr
00417 #endif
00418 }
00419
00423 inline vector_type& normalize()
00424 {
00425 *this /= norm();
00426 return *this;
00427 }
00428
00431 inline vector_type& normalize_cond()
00432 {
00433 Scalar n = norm();
00434 if (n != (Scalar)0.0)
00435 {
00436 *this /= n;
00437 }
00438 return *this;
00439 }
00440
00442
00443
00444
00446
00447
00449 inline Scalar l1_norm() const
00450 {
00451 #if DIM==N
00452 Scalar s(0);
00453 #define expr(i) s += abs(Base::values_[i]);
00454 unroll(expr);
00455 #undef expr
00456 return s;
00457 #else
00458 #define expr(i) abs(Base::values_[i])
00459 return (unroll_comb(expr, +));
00460 #undef expr
00461 #endif
00462 }
00463
00465 inline Scalar l8_norm() const
00466 {
00467 return max_abs();
00468 }
00469
00471
00472
00473
00475
00476
00478 inline Scalar max() const
00479 {
00480 Scalar m(Base::values_[0]);
00481 for(int i=1; i<DIM; ++i) if(Base::values_[i]>m) m=Base::values_[i];
00482 return m;
00483 }
00484
00486 inline Scalar max_abs() const
00487 {
00488 Scalar m(abs(Base::values_[0]));
00489 for(int i=1; i<DIM; ++i)
00490 if(abs(Base::values_[i])>m)
00491 m=abs(Base::values_[i]);
00492 return m;
00493 }
00494
00495
00497 inline Scalar min() const
00498 {
00499 Scalar m(Base::values_[0]);
00500 for(int i=1; i<DIM; ++i) if(Base::values_[i]<m) m=Base::values_[i];
00501 return m;
00502 }
00503
00505 inline Scalar min_abs() const
00506 {
00507 Scalar m(abs(Base::values_[0]));
00508 for(int i=1; i<DIM; ++i)
00509 if(abs(Base::values_[i])<m)
00510 m=abs(Base::values_[i]);
00511 return m;
00512 }
00513
00515 inline Scalar mean() const {
00516 Scalar m(Base::values_[0]);
00517 for(int i=1; i<DIM; ++i) m+=Base::values_[i];
00518 return m/Scalar(DIM);
00519 }
00520
00522 inline Scalar mean_abs() const {
00523 Scalar m(abs(Base::values_[0]));
00524 for(int i=1; i<DIM; ++i) m+=abs(Base::values_[i]);
00525 return m/Scalar(DIM);
00526 }
00527
00528
00530 inline vector_type minimize(const vector_type& _rhs) {
00531 #define expr(i) if (_rhs[i] < Base::values_[i]) Base::values_[i] = _rhs[i];
00532 unroll(expr);
00533 #undef expr
00534 return *this;
00535 }
00536
00538 inline bool minimized(const vector_type& _rhs) {
00539 bool result(false);
00540 #define expr(i) if (_rhs[i] < Base::values_[i]) { Base::values_[i] = _rhs[i]; result = true; }
00541 unroll(expr);
00542 #undef expr
00543 return result;
00544 }
00545
00547 inline vector_type maximize(const vector_type& _rhs) {
00548 #define expr(i) if (_rhs[i] > Base::values_[i]) Base::values_[i] = _rhs[i];
00549 unroll(expr);
00550 #undef expr
00551 return *this;
00552 }
00553
00555 inline bool maximized(const vector_type& _rhs) {
00556 bool result(false);
00557 #define expr(i) if (_rhs[i] > Base::values_[i]) { Base::values_[i] =_rhs[i]; result = true; }
00558 unroll(expr);
00559 #undef expr
00560 return result;
00561 }
00562
00564 inline vector_type min(const vector_type& _rhs) {
00565 return vector_type(*this).minimize(_rhs);
00566 }
00567
00569 inline vector_type max(const vector_type& _rhs) {
00570 return vector_type(*this).maximize(_rhs);
00571 }
00572
00574
00575
00576
00578 template<typename Functor>
00579 inline vector_type apply(const Functor& _func) const {
00580 vector_type result;
00581 #define expr(i) result[i] = _func(Base::values_[i]);
00582 unroll(expr);
00583 #undef expr
00584 return result;
00585 }
00586
00588 vector_type& vectorize(const Scalar& _s) {
00589 #define expr(i) Base::values_[i] = _s;
00590 unroll(expr);
00591 #undef expr
00592 return *this;
00593 }
00594
00595
00597 static vector_type vectorized(const Scalar& _s) {
00598 return vector_type().vectorize(_s);
00599 }
00600
00601
00603 bool operator<(const vector_type& _rhs) const {
00604 #define expr(i) if (Base::values_[i] != _rhs.Base::values_[i]) \
00605 return (Base::values_[i] < _rhs.Base::values_[i]);
00606 unroll(expr);
00607 #undef expr
00608 return false;
00609 }
00610 };
00611
00612
00613
00615 TEMPLATE_HEADER
00616 inline std::istream&
00617 operator>>(std::istream& is, VectorT<Scalar,DIM>& vec)
00618 {
00619 #define expr(i) is >> vec[i];
00620 unroll(expr);
00621 #undef expr
00622 return is;
00623 }
00624
00625
00627 TEMPLATE_HEADER
00628 inline std::ostream&
00629 operator<<(std::ostream& os, const VectorT<Scalar,DIM>& vec)
00630 {
00631 #if DIM==N
00632 for(int i=0; i<N-1; ++i) os << vec[i] << " ";
00633 os << vec[N-1];
00634 #else
00635 #define expr(i) vec[i]
00636 os << unroll_comb(expr, << " " <<);
00637 #undef expr
00638 #endif
00639
00640 return os;
00641 }
00642
00643
00644
00645 #endif // included by VectorT.hh
00646