OpenMesh
OpenMesh/Core/Geometry/VectorT_inc.hh
00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                               OpenMesh                                    *
00004  *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openmesh.org                                *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------* 
00008  *  This file is part of OpenMesh.                                           *
00009  *                                                                           *
00010  *  OpenMesh is free software: you can redistribute it and/or modify         * 
00011  *  it under the terms of the GNU Lesser General Public License as           *
00012  *  published by the Free Software Foundation, either version 3 of           *
00013  *  the License, or (at your option) any later version with the              *
00014  *  following exceptions:                                                    *
00015  *                                                                           *
00016  *  If other files instantiate templates or use macros                       *
00017  *  or inline functions from this file, or you compile this file and         *
00018  *  link it with other files to produce an executable, this file does        *
00019  *  not by itself cause the resulting executable to be covered by the        *
00020  *  GNU Lesser General Public License. This exception does not however       *
00021  *  invalidate any other reasons why the executable file might be            *
00022  *  covered by the GNU Lesser General Public License.                        *
00023  *                                                                           *
00024  *  OpenMesh is distributed in the hope that it will be useful,              *
00025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
00027  *  GNU Lesser General Public License for more details.                      *
00028  *                                                                           *
00029  *  You should have received a copy of the GNU LesserGeneral Public          *
00030  *  License along with OpenMesh.  If not,                                    *
00031  *  see <http://www.gnu.org/licenses/>.                                      *
00032  *                                                                           *
00033 \*===========================================================================*/ 
00034 
00035 /*===========================================================================*\
00036  *                                                                           *             
00037  *   $Revision: 362 $                                                         *
00038  *   $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 2011) $                   *
00039  *                                                                           *
00040 \*===========================================================================*/
00041 
00042 // Set template keywords and class names properly when
00043 // parsing with doxygen. This only seems to work this way since
00044 // the scope of preprocessor defines is limited to one file in doxy.
00045 #ifdef DOXYGEN
00046 
00047 // Only used for correct doxygen parsing
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   //---------------------------------------------------------------- class info
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   //-------------------------------------------------------------- constructors
00087 
00089   inline VectorT() {}
00090 
00092   explicit inline VectorT(const Scalar& v) {
00093 //     assert(DIM==1);
00094 //     values_[0] = v0;
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   // mipspro need this method
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   //--------------------------------------------------------------------- casts
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 //   /// cast to Scalar array
00169 //   inline operator Scalar*() { return Base::values_; }
00170 
00171 //   /// cast to const Scalar array
00172 //   inline operator const Scalar*() const { return Base::values_; }
00173 
00175   inline Scalar* data() { return Base::values_; }
00176 
00178   inline const Scalar*data() const { return Base::values_; }
00179 
00180 
00181 
00182 
00183    //----------------------------------------------------------- element access
00184 
00185 //    /// get i'th element read-write
00186 //   inline Scalar& operator[](int _i) {
00187 //     assert(_i>=0 && _i<DIM); return Base::values_[_i];
00188 //   }
00189 
00190 //   /// get i'th element read-only
00191 //   inline const Scalar& operator[](int _i) const {
00192 //     assert(_i>=0 && _i<DIM); return Base::values_[_i];
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   //---------------------------------------------------------------- comparsion
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   //---------------------------------------------------------- scalar operators
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   //---------------------------------------------------------- vector operators
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   //------------------------------------------------------------ euclidean norm
00397 
00399 
00400 
00401   inline Scalar norm() const { return (Scalar)sqrt(sqrnorm()); }
00402   inline Scalar length() const { return norm(); } // OpenSG interface
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   //------------------------------------------------------------ euclidean norm
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   //------------------------------------------------------------ max, min, mean
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   //------------------------------------------------------------ misc functions
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 //=============================================================================