//============================================================================= // // OpenMesh // Copyright (C) 2003 by Computer Graphics Group, RWTH Aachen // www.openmesh.org // //----------------------------------------------------------------------------- // // License // // This library is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License as published // by the Free Software Foundation, version 2. // // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // //----------------------------------------------------------------------------- // // $Revision: 1801 $ // $Date: 2008-05-19 11:53:56 +0200 (Mo, 19. Mai 2008) $ // //============================================================================= #if defined( OPENMESH_VECTOR_HH ) // ---------------------------------------------------------------------------- TEMPLATE_HEADER class CLASSNAME : public DERIVED { private: typedef DERIVED Base; public: //---------------------------------------------------------------- class info /// the type of the scalar used in this template typedef Scalar value_type; /// type of this vector typedef VectorT vector_type; /// returns dimension of the vector (deprecated) static inline int dim() { return DIM; } /// returns dimension of the vector static inline size_t size() { return DIM; } static const size_t size_ = DIM; //-------------------------------------------------------------- constructors /// default constructor creates uninitialized values. inline VectorT() {} /// special constructor for 1D vectors explicit inline VectorT(const Scalar& v) { // assert(DIM==1); // values_[0] = v0; vectorize(v); } /// special constructor for 2D vectors inline VectorT(const Scalar& v0, const Scalar& v1) { assert(DIM==2); Base::values_[0] = v0; Base::values_[1] = v1; } /// special constructor for 3D vectors inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2) { assert(DIM==3); Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; } /// special constructor for 4D vectors inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2, const Scalar& v3) { assert(DIM==4); Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; Base::values_[3]=v3; } /// special constructor for 5D vectors inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2, const Scalar& v3, const Scalar& v4) { assert(DIM==5); Base::values_[0]=v0; Base::values_[1]=v1;Base::values_[2]=v2; Base::values_[3]=v3; Base::values_[4]=v4; } /// special constructor for 6D vectors inline VectorT(const Scalar& v0, const Scalar& v1, const Scalar& v2, const Scalar& v3, const Scalar& v4, const Scalar& v5) { assert(DIM==6); Base::values_[0]=v0; Base::values_[1]=v1; Base::values_[2]=v2; Base::values_[3]=v3; Base::values_[4]=v4; Base::values_[5]=v5; } /// construct from a value array (explicit) explicit inline VectorT(const Scalar _values[DIM]) { memcpy(Base::values_, _values, DIM*sizeof(Scalar)); } #ifdef OM_CC_MIPS /// assignment from a vector of the same kind // mipspro need this method inline vector_type& operator=(const vector_type& _rhs) { memcpy(Base::values_, _rhs.Base::values_, DIM*sizeof(Scalar)); return *this; } #endif /// copy & cast constructor (explicit) template explicit inline VectorT(const VectorT& _rhs) { operator=(_rhs); } //--------------------------------------------------------------------- casts /// cast from vector with a different scalar type template inline vector_type& operator=(const VectorT& _rhs) { #define expr(i) Base::values_[i] = (Scalar)_rhs[i]; unroll(expr); #undef expr return *this; } // /// cast to Scalar array // inline operator Scalar*() { return Base::values_; } // /// cast to const Scalar array // inline operator const Scalar*() const { return Base::values_; } /// access to Scalar array inline Scalar* data() { return Base::values_; } /// access to const Scalar array inline const Scalar*data() const { return Base::values_; } //----------------------------------------------------------- element access // /// get i'th element read-write // inline Scalar& operator[](int _i) { // assert(_i>=0 && _i=0 && _i operator%(const VectorT& _rhs) const #if DIM==3 { return VectorT(Base::values_[1]*_rhs.Base::values_[2]-Base::values_[2]*_rhs.Base::values_[1], Base::values_[2]*_rhs.Base::values_[0]-Base::values_[0]*_rhs.Base::values_[2], Base::values_[0]*_rhs.Base::values_[1]-Base::values_[1]*_rhs.Base::values_[0]); } #else ; #endif /// compute scalar product /// \see OpenMesh::dot inline Scalar operator|(const vector_type& _rhs) const { Scalar p(0); #define expr(i) p += Base::values_[i] * _rhs.Base::values_[i]; unroll(expr); #undef expr return p; } //------------------------------------------------------------ euclidean norm /// \name Euclidean norm calculations //@{ /// compute euclidean norm inline Scalar norm() const { return (Scalar)sqrt(sqrnorm()); } inline Scalar length() const { return norm(); } // OpenSG interface /// compute squared euclidean norm inline Scalar sqrnorm() const { #if DIM==N Scalar s(0); #define expr(i) s += Base::values_[i] * Base::values_[i]; unroll(expr); #undef expr return s; #else #define expr(i) Base::values_[i]*Base::values_[i] return (unroll_comb(expr, +)); #undef expr #endif } //@} /** normalize vector, return normalized vector */ inline vector_type& normalize() { *this /= norm(); return *this; } /** normalize vector, return normalized vector and avoids div by zero */ inline vector_type& normalize_cond() { Scalar n = norm(); if (n != (Scalar)0.0) { *this /= n; } return *this; } //------------------------------------------------------------ max, min, mean /// return the maximal component inline Scalar max() const { Scalar m(Base::values_[0]); for(int i=1; im) m=Base::values_[i]; return m; } /// return the minimal component inline Scalar min() const { Scalar m(Base::values_[0]); for(int i=1; i Base::values_[i]) Base::values_[i] = _rhs[i]; unroll(expr); #undef expr return *this; } /// component-wise min inline vector_type min(const vector_type& _rhs) { return vector_type(*this).minimize(_rhs); } /// component-wise max inline vector_type max(const vector_type& _rhs) { return vector_type(*this).maximize(_rhs); } //------------------------------------------------------------ misc functions /// component-wise apply function object with Scalar operator()(Scalar). template inline vector_type apply(const Functor& _func) const { vector_type result; #define expr(i) result[i] = _func(Base::values_[i]); unroll(expr); #undef expr return result; } /// store the same value in each component (e.g. to clear all entries) vector_type& vectorize(const Scalar& _s) { #define expr(i) Base::values_[i] = _s; unroll(expr); #undef expr return *this; } /// store the same value in each component static vector_type vectorized(const Scalar& _s) { return vector_type().vectorize(_s); } /// lexicographical comparison bool operator<(const vector_type& _rhs) const { #define expr(i) if (Base::values_[i] != _rhs.Base::values_[i]) \ return (Base::values_[i] < _rhs.Base::values_[i]); unroll(expr); #undef expr return false; } }; /// read the space-separated components of a vector from a stream TEMPLATE_HEADER inline std::istream& operator>>(std::istream& is, VectorT& vec) { #define expr(i) is >> vec[i]; unroll(expr); #undef expr return is; } /// output a vector by printing its space-separated compontens TEMPLATE_HEADER inline std::ostream& operator<<(std::ostream& os, const VectorT& vec) { #if DIM==N for(int i=0; i