diff --git a/vcg/complex/trimesh/clean.h b/vcg/complex/trimesh/clean.h index a3f4f30a..27c0393f 100644 --- a/vcg/complex/trimesh/clean.h +++ b/vcg/complex/trimesh/clean.h @@ -1152,7 +1152,7 @@ static bool TestIntersection(FaceType *f0,FaceType *f1) //no adiacent faces if ( (f0!=f1) && (!ShareEdge(f0,f1)) && (!ShareVertex(f0,f1)) ) - return (vcg::Intersection_((*f0),(*f1))); + return (vcg::Intersection((*f0),(*f1))); return false; } diff --git a/vcg/math/eigen.h b/vcg/math/eigen.h index 642616df..17359802 100644 --- a/vcg/math/eigen.h +++ b/vcg/math/eigen.h @@ -28,12 +28,18 @@ #define EIGEN_DONT_VECTORIZE #define EIGEN_MATRIXBASE_PLUGIN +// forward declarations +namespace Eigen { +template struct ei_lexi_comparison; +} + #include "../Eigen/LU" #include "../Eigen/Geometry" #include "../Eigen/Array" #include "../Eigen/Core" #include "base.h" +// add support for unsigned char and short int namespace Eigen { template<> struct NumTraits { @@ -61,6 +67,94 @@ template<> struct NumTraits }; }; +// WARNING this is a default version provided so that Intersection() stuff can compile. +// Indeed, the compiler try to instanciate all versions of Intersection() leading to +// the instanciation of Eigen::Matrix !!! +template struct NumTraits +{ + struct wrong_type + { + wrong_type() { assert(0 && "Eigen: you are using a wrong scalar type" ); } + }; + + typedef wrong_type Real; + typedef wrong_type FloatingPoint; + enum { + IsComplex = 0, + HasFloatingPoint = 0, + ReadCost = 0, + AddCost = 0, + MulCost = 0 + }; +}; + +// implementation of Lexicographic order comparison +// TODO should use meta unrollers +template struct ei_lexi_comparison +{ + inline static bool less(const Derived1& a, const Derived2& b) { + return (a.coeff(1)!=b.coeff(1))?(a.coeff(1)< b.coeff(1)) : (a.coeff(0) b.coeff(1)) : (a.coeff(0)>b.coeff(0)); + } + + inline static bool lessEqual(const Derived1& a, const Derived2& b) { + return (a.coeff(1)!=b.coeff(1))?(a.coeff(1)< b.coeff(1)) : (a.coeff(0)<=b.coeff(0)); + } + + inline static bool greaterEqual(const Derived1& a, const Derived2& b) { + return (a.coeff(1)!=b.coeff(1))?(a.coeff(1)> b.coeff(1)) : (a.coeff(0)>=b.coeff(0)); + } +}; + +template struct ei_lexi_comparison +{ + inline static bool less(const Derived1& a, const Derived2& b) { + return (a.coeff(2)!=b.coeff(2))?(a.coeff(2)< b.coeff(2)): + (a.coeff(1)!=b.coeff(1))?(a.coeff(1)< b.coeff(1)) : (a.coeff(0) b.coeff(2)): + (a.coeff(1)!=b.coeff(1))?(a.coeff(1)> b.coeff(1)) : (a.coeff(0)>b.coeff(0)); + } + + inline static bool lessEqual(const Derived1& a, const Derived2& b) { + return (a.coeff(2)!=b.coeff(2))?(a.coeff(2)< b.coeff(2)): + (a.coeff(1)!=b.coeff(1))?(a.coeff(1)< b.coeff(1)) : (a.coeff(0)<=b.coeff(0)); + } + + inline static bool greaterEqual(const Derived1& a, const Derived2& b) { + return (a.coeff(2)!=b.coeff(2))?(a.coeff(2)> b.coeff(2)): + (a.coeff(1)!=b.coeff(1))?(a.coeff(1)> b.coeff(1)) : (a.coeff(0)>=b.coeff(0)); + } +}; + +template struct ei_lexi_comparison +{ + inline static bool less(const Derived1& a, const Derived2& b) { + return (a.coeff(3)!=b.coeff(3))?(a.coeff(3)< b.coeff(3)) : (a.coeff(2)!=b.coeff(2))?(a.coeff(2)< b.coeff(2)): + (a.coeff(1)!=b.coeff(1))?(a.coeff(1)< b.coeff(1)) : (a.coeff(0) b.coeff(3)) : (a.coeff(2)!=b.coeff(2))?(a.coeff(2)> b.coeff(2)): + (a.coeff(1)!=b.coeff(1))?(a.coeff(1)> b.coeff(1)) : (a.coeff(0)>b.coeff(0)); + } + + inline static bool lessEqual(const Derived1& a, const Derived2& b) { + return (a.coeff(3)!=b.coeff(3))?(a.coeff(3)< b.coeff(3)) : (a.coeff(2)!=b.coeff(2))?(a.coeff(2)< b.coeff(2)): + (a.coeff(1)!=b.coeff(1))?(a.coeff(1)< b.coeff(1)) : (a.coeff(0)<=b.coeff(0)); + } + + inline static bool greaterEqual(const Derived1& a, const Derived2& b) { + return (a.coeff(3)!=b.coeff(3))?(a.coeff(3)> b.coeff(3)) : (a.coeff(2)!=b.coeff(2))?(a.coeff(2)> b.coeff(2)): + (a.coeff(1)!=b.coeff(1))?(a.coeff(1)> b.coeff(1)) : (a.coeff(0)>=b.coeff(0)); + } +}; + } #define VCG_EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, Op) \ @@ -110,6 +204,23 @@ Angle(const Eigen::MatrixBase& p1, const Eigen::MatrixBase & return vcg::math::Acos(t); } +template +typename Eigen::ei_traits::Scalar +AngleN(const Eigen::MatrixBase& p1, const Eigen::MatrixBase & p2) +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived1) + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived2) + EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived1) + EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived2) + EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived1,Derived2) + typedef typename Eigen::ei_traits::Scalar Scalar; + + Scalar t = (p1.dot(p2)); + if(t>1) t = 1; + else if(t<-1) t = -1; + return vcg::math::Acos(t); +} + template inline typename Eigen::ei_traits::Scalar Norm( const Eigen::MatrixBase& p) { return p.norm(); } diff --git a/vcg/math/eigen_vcgaddons.h b/vcg/math/eigen_vcgaddons.h index fa520472..aba3c936 100644 --- a/vcg/math/eigen_vcgaddons.h +++ b/vcg/math/eigen_vcgaddons.h @@ -40,8 +40,10 @@ EIGEN_DEPRECATED inline unsigned int RowsNumber() const { return rows(); }; * \param j the column index * \return the element */ -EIGEN_DEPRECATED inline Scalar ElementAt(unsigned int i, unsigned int j) const { return (*this)(i,j); } -EIGEN_DEPRECATED inline Scalar& ElementAt(unsigned int i, unsigned int j) { return (*this)(i,j); } +EIGEN_DEPRECATED inline Scalar ElementAt(unsigned int i, unsigned int j) const { return (*this)(i,j); }; +EIGEN_DEPRECATED inline Scalar& ElementAt(unsigned int i, unsigned int j) { return (*this)(i,j); }; +EIGEN_DEPRECATED inline Scalar V(int i) const { return (*this)[i]; }; +EIGEN_DEPRECATED inline Scalar& V(int i) { return (*this)[i]; }; /*! * \deprecated use *this.determinant() (or *this.lu().determinant() for large matrices) @@ -188,12 +190,110 @@ EIGEN_DEPRECATED void Dump() } /** \deprecated use norm() */ -EIGEN_DEPRECATED inline Scalar Norm() const { return norm(); } +EIGEN_DEPRECATED inline Scalar Norm() const { return norm(); }; /** \deprecated use squaredNorm() */ -EIGEN_DEPRECATED inline Scalar SquaredNorm() const { return norm2(); } +EIGEN_DEPRECATED inline Scalar SquaredNorm() const { return norm2(); }; /** \deprecated use normalize() or normalized() */ -EIGEN_DEPRECATED inline Derived& Normalize() { normalize(); return derived(); } +EIGEN_DEPRECATED inline Derived& Normalize() { normalize(); return derived(); }; +/** \deprecated use normalized() */ +EIGEN_DEPRECATED inline const EvalType Normalize() const { return normalized(); }; /** \deprecated use .cross(p) */ EIGEN_DEPRECATED inline EvalType operator ^ (const Derived& p ) const { return this->cross(p); } +/// Homogeneous normalization (division by W) +inline Derived& HomoNormalize() +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); + enum { + SubRows = (int(Flags)&RowMajorBit) ? 1 : (RowsAtCompileTime==Dynamic ? Dynamic : RowsAtCompileTime-1), + SubCols = (int(Flags)&RowMajorBit) ? (ColsAtCompileTime==Dynamic ? Dynamic : ColsAtCompileTime-1) : 1, + }; + Scalar& last = coeffRef(size()-2); + if (last!=Scalar(0)) + { + Block(derived(),0,0, + (int(Flags)&RowMajorBit) ? size()-1 : 1, + (int(Flags)&RowMajorBit) ? 1 : (size()-1)) / last; + last = Scalar(1.0); + } + return *this; +} + +inline const EvalType HomoNormalize() const +{ + EvalType res = derived(); + return res.HomoNormalize(); +} + +/// norm infinity: largest absolute value of compoenet +EIGEN_DEPRECATED inline Scalar NormInfinity() const { return derived().cwise().abs().maxCoeff(); } +/// norm 1: sum of absolute values of components +EIGEN_DEPRECATED inline Scalar NormOne() const { return derived().cwise().abs().sum(); } + + +/// the sum of the components +EIGEN_DEPRECATED inline Scalar Sum() const { return sum(); } +/// returns the biggest component +EIGEN_DEPRECATED inline Scalar Max() const { return maxCoeff(); } +/// returns the smallest component +EIGEN_DEPRECATED inline Scalar Min() const { return minCoeff(); } +/// returns the index of the biggest component +EIGEN_DEPRECATED inline int MaxI() const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); int i; maxCoeff(&i,0); return i; } +/// returns the index of the smallest component +EIGEN_DEPRECATED inline int MinI() const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); int i; minCoeff(&i,0); return i; } + + +/// Padding function: give a default 0 value to all the elements that are not in the [0..2] range. +/// Useful for managing in a consistent way object that could have point2 / point3 / point4 +inline Scalar Ext( const int i ) const +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); + EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived); + + if(i>=0 && i +EIGEN_DEPRECATED inline Derived& Scale(const MatrixBase& other) +{ this->cwise() *= other; return derived; } + +template +EIGEN_DEPRECATED inline +CwiseBinaryOp, Derived, OtherDerived> +Scale(const MatrixBase& other) const +{ return this->cwise() * other; } + + +template +EIGEN_DEPRECATED inline bool operator < (const MatrixBase& other) const { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); + EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived); + return ei_lexi_comparison::less(derived(),other.derived()); +} + +template +EIGEN_DEPRECATED inline bool operator > (const MatrixBase& other) const { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); + EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived); + return ei_lexi_comparison::geater(derived(),other.derived()); +} + +template +EIGEN_DEPRECATED inline bool operator <= (const MatrixBase& other) const { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); + EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived); + return ei_lexi_comparison::lessEqual(derived(),other.derived()); +} + +template +EIGEN_DEPRECATED inline bool operator >= (const MatrixBase& other) const { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived); + EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived); + return ei_lexi_comparison::greaterEqual(derived(),other.derived()); +} diff --git a/vcg/math/matrix.h b/vcg/math/matrix.h index 28db42df..75ac9b53 100644 --- a/vcg/math/matrix.h +++ b/vcg/math/matrix.h @@ -50,6 +50,7 @@ namespace ndim{ /* @{ */ /*! + * \deprecated use Matrix or Matrix * This class represent a generic mn matrix. The class is templated over the scalar type field. * @param Scalar (Templete Parameter) Specifies the ScalarType field. */ @@ -135,6 +136,7 @@ public: * \param reference to the matrix to multiply by * \return the matrix product */ + // FIXME what the hell is that ! /*template void DotProduct(Point &m,Point &result) { @@ -147,7 +149,7 @@ public: };*/ /*! - * \deprecated use *this.resize() + * \deprecated use *this.resize(); *this.setZero(); * Resize the current matrix. * \param m the number of matrix rows. * \param n the number of matrix columns. @@ -159,11 +161,6 @@ public: Base::resize(m,n); memset(Base::data(), 0, m*n*sizeof(Scalar)); }; - -// EIGEN_DEPRECATED void Transpose() -// { -// assert(0 && "dangerous use of deprecated Transpose function, please use: m = m.transpose();"); -// } }; typedef vcg::ndim::Matrix MatrixMNd; diff --git a/vcg/space/deprecated_point.h b/vcg/space/deprecated_point.h new file mode 100644 index 00000000..9fb74eff --- /dev/null +++ b/vcg/space/deprecated_point.h @@ -0,0 +1,980 @@ +/**************************************************************************** +* VCGLib o o * +* Visual and Computer Graphics Library o o * +* _ O _ * +* Copyright(C) 2004 \/)\/ * +* Visual Computing Lab /\/| * +* ISTI - Italian National Research Council | * +* \ * +* All rights reserved. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program 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 General Public License (http://www.gnu.org/licenses/gpl.txt) * +* for more details. * +* * +****************************************************************************/ +/**************************************************************************** + History + +$Log: not supported by cvs2svn $ +Revision 1.9 2006/12/20 15:23:52 ganovelli +using of locally defined variable removed + +Revision 1.8 2006/04/11 08:10:05 zifnab1974 +changes necessary for gcc 3.4.5 on linux 64bit. + +Revision 1.7 2005/12/12 11:22:32 ganovelli +compiled with gcc + +Revision 1.6 2005/01/12 11:25:52 ganovelli +corrected Point<3 + +Revision 1.5 2004/10/20 16:45:21 ganovelli +first compiling version (MC,INtel,gcc) + +Revision 1.4 2004/04/29 10:47:06 ganovelli +some siyntax error corrected + +Revision 1.3 2004/04/05 12:36:43 tarini +unified version: PointBase version, with no guards "(N==3)" + + + +Revision 1.1 2004/03/16 03:07:38 tarini +"dimensionally unified" version: first commit + +****************************************************************************/ + +#ifndef __VCGLIB_POINT +#define __VCGLIB_POINT + +#include +#include +#include + +namespace vcg { + + namespace ndim{ + + +//template +//class Point; + +/** \addtogroup space */ +/*@{*/ + /** + The templated class for representing a point in R^N space. + The class is templated over the ScalarType class that is used to represent coordinates. + PointBase provides the interface and the common operators for points + of any dimensionality. + */ + +template +class Point +{ +public: + typedef S ScalarType; + typedef VoidType ParamType; + typedef Point PointType; + enum {Dimension=N}; + + +protected: + /// The only data member. Hidden to user. + S _v[N]; + +public: + +//@{ + + /** @name Standard Constructors and Initializers + No casting operators have been introduced to avoid automatic unattended (and costly) conversion between different PointType types + **/ + + inline Point () { }; +// inline Point ( const S nv[N] ); + + /// Padding function: give a default 0 value to all the elements that are not in the [0..2] range. + /// Useful for managing in a consistent way object that could have point2 / point3 / point4 + inline S Ext( const int i ) const + { + if(i>=0 && i<=N) return _v[i]; + else return 0; + } + + /// importer for points with different scalar type and-or dimensionality + template + inline void Import( const Point & b ) + { + _v[0] = ScalarType(b[0]); + _v[1] = ScalarType(b[1]); + if (N>2) { if (N2>2) _v[2] = ScalarType(b[2]); else _v[2] = 0;}; + if (N>3) { if (N2>3) _v[3] = ScalarType(b[3]); else _v[3] = 0;}; + } + + /// constructor for points with different scalar type and-or dimensionality + template + static inline PointType Construct( const Point & b ) + { + PointType p; p.Import(b); + return p; + } + + /// importer for homogeneous points + template + inline void ImportHomo( const Point & b ) + { + _v[0] = ScalarType(b[0]); + _v[1] = ScalarType(b[1]); + if (N>2) { _v[2] = ScalarType(_v[2]); }; + _v[N-1] = 1.0; + } + + /// constructor for homogeneus point. + template + static inline PointType Construct( const Point & b ) + { + PointType p; p.ImportHomo(b); + return p; + } + +//@} + +//@{ + + /** @name Data Access. + access to data is done by overloading of [] or explicit naming of coords (x,y,z)**/ + + inline S & operator [] ( const int i ) + { + assert(i>=0 && i=0 && i2); return _v[2]; } + /// W is in any case the last coordinate. + /// (in a 2D point, W() == Y(). In a 3D point, W()==Z() + /// in a 4D point, W() is a separate component) + inline const S &W() const { return _v[N-1]; } + inline S &X() { return _v[0]; } + inline S &Y() { return _v[1]; } + inline S &Z() { static_assert(N>2); return _v[2]; } + inline S &W() { return _v[N-1]; } + inline const S * V() const + { + return _v; + } + inline S & V( const int i ) + { + assert(i>=0 && i=0 && i static S Norm(const PT &p ); + /// Squared Euclidean norm + inline S SquaredNorm() const; + /// Squared Euclidean norm, static version + template static S SquaredNorm(const PT &p ); + /// Normalization (division by norm) + inline PointType & Normalize(); + /// Normalization (division by norm), static version + template static PointType & Normalize(const PT &p); + /// Homogeneous normalization (division by W) + inline PointType & HomoNormalize(); + + /// norm infinity: largest absolute value of compoenet + inline S NormInfinity() const; + /// norm 1: sum of absolute values of components + inline S NormOne() const; + +//@} + /// Signed area operator + /// a % b returns the signed area of the parallelogram inside a and b + inline S operator % ( PointType const & p ) const; + + /// the sum of the components + inline S Sum() const; + /// returns the biggest component + inline S Max() const; + /// returns the smallest component + inline S Min() const; + /// returns the index of the biggest component + inline int MaxI() const; + /// returns the index of the smallest component + inline int MinI() const; + + + /// Per component scaling + inline PointType & Scale( const PointType & p ); + + + /// Convert to polar coordinates + void ToPolar( S & ro, S & tetha, S & fi ) const + { + ro = Norm(); + tetha = (S)atan2( _v[1], _v[0] ); + fi = (S)acos( _v[2]/ro ); + } + +//@{ + + /** @name Comparison Operators. + Lexicographic order. + **/ + + inline bool operator == ( PointType const & p ) const; + inline bool operator != ( PointType const & p ) const; + inline bool operator < ( PointType const & p ) const; + inline bool operator > ( PointType const & p ) const; + inline bool operator <= ( PointType const & p ) const; + inline bool operator >= ( PointType const & p ) const; + //@} + +//@{ + + /** @name + Glocal to Local and viceversa + (provided for uniformity with other spatial classes. trivial for points) + **/ + + inline PointType LocalToGlobal(ParamType p) const{ + return *this; } + + inline ParamType GlobalToLocal(PointType p) const{ + ParamType p(); return p; } +//@} + +}; // end class definition + + + + + + + + + +template +class Point2 : public Point<2,S> { +public: + typedef S ScalarType; + typedef Point2 PointType; + using Point<2,S>::_v; + using Point<2,S>::V; + using Point<2,S>::W; + + //@{ + /** @name Special members for 2D points. **/ + + /// default + inline Point2 (){} + + /// yx constructor + inline Point2 ( const S a, const S b){ + _v[0]=a; _v[1]=b; }; + + /// unary orthogonal operator (2D equivalent of cross product) + /// returns orthogonal vector (90 deg left) + inline Point2 operator ~ () const { + return Point2 ( -_v[2], _v[1] ); + } + + /// returns the angle with X axis (radiants, in [-PI, +PI] ) + inline ScalarType &Angle(){ + return math::Atan2(_v[1],_v[0]);} + + /// transform the point in cartesian coords into polar coords + inline Point2 & ToPolar(){ + ScalarType t = Angle(); + _v[0] = Norm(); + _v[1] = t; + return *this;} + + /// transform the point in polar coords into cartesian coords + inline Point2 & ToCartesian() { + ScalarType l = _v[0]; + _v[0] = (ScalarType)(l*math::Cos(_v[1])); + _v[1] = (ScalarType)(l*math::Sin(_v[1])); + return *this;} + + /// rotates the point of an angle (radiants, counterclockwise) + inline Point2 & Rotate( const ScalarType rad ){ + ScalarType t = _v[0]; + ScalarType s = math::Sin(rad); + ScalarType c = math::Cos(rad); + _v[0] = _v[0]*c - _v[1]*s; + _v[1] = t *s + _v[1]*c; + return *this;} + + //@} + + //@{ + /** @name Implementation of standard functions for 3D points **/ + + inline void Zero(){ + _v[0]=0; _v[1]=0; }; + + inline Point2 ( const S nv[2] ){ + _v[0]=nv[0]; _v[1]=nv[1]; }; + + inline Point2 operator + ( Point2 const & p) const { + return Point2( _v[0]+p._v[0], _v[1]+p._v[1]); } + + inline Point2 operator - ( Point2 const & p) const { + return Point2( _v[0]-p._v[0], _v[1]-p._v[1]); } + + inline Point2 operator * ( const S s ) const { + return Point2( _v[0]*s, _v[1]*s ); } + + inline Point2 operator / ( const S s ) const { + S t=1.0/s; + return Point2( _v[0]*t, _v[1]*t ); } + + inline Point2 operator - () const { + return Point2 ( -_v[0], -_v[1] ); } + + inline Point2 & operator += ( Point2 const & p ) { + _v[0] += p._v[0]; _v[1] += p._v[1]; return *this; } + + inline Point2 & operator -= ( Point2 const & p ) { + _v[0] -= p._v[0]; _v[1] -= p._v[1]; return *this; } + + inline Point2 & operator *= ( const S s ) { + _v[0] *= s; _v[1] *= s; return *this; } + + inline Point2 & operator /= ( const S s ) { + S t=1.0/s; _v[0] *= t; _v[1] *= t; return *this; } + + inline S Norm() const { + return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] );} + + template static S Norm(const PT &p ) { + return math::Sqrt( p.V(0)*p.V(0) + p.V(1)*p.V(1) );} + + inline S SquaredNorm() const { + return ( _v[0]*_v[0] + _v[1]*_v[1] );} + + template static S SquaredNorm(const PT &p ) { + return ( p.V(0)*p.V(0) + p.V(1)*p.V(1) );} + + inline S operator * ( Point2 const & p ) const { + return ( _v[0]*p._v[0] + _v[1]*p._v[1]) ; } + + inline bool operator == ( Point2 const & p ) const { + return _v[0]==p._v[0] && _v[1]==p._v[1] ;} + + inline bool operator != ( Point2 const & p ) const { + return _v[0]!=p._v[0] || _v[1]!=p._v[1] ;} + + inline bool operator < ( Point2 const & p ) const{ + return (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0] ( Point2 const & p ) const { + return (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>p._v[0]); } + + inline bool operator <= ( Point2 const & p ) { + return (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0]<=p._v[0]); } + + inline bool operator >= ( Point2 const & p ) const { + return (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>=p._v[0]); } + + inline Point2 & Normalize() { + PointType n = Norm(); if(n!=0.0) { n=1.0/n; _v[0]*=n; _v[1]*=n;} return *this;}; + + template Point2 & Normalize(const PT &p){ + PointType n = Norm(); if(n!=0.0) { n=1.0/n; V(0)*=n; V(1)*=n; } + return *this;}; + + inline Point2 & HomoNormalize(){ + if (_v[2]!=0.0) { _v[0] /= W(); W()=1.0; } return *this;}; + + inline S NormInfinity() const { + return math::Max( math::Abs(_v[0]), math::Abs(_v[1]) ); } + + inline S NormOne() const { + return math::Abs(_v[0])+ math::Abs(_v[1]);} + + inline S operator % ( Point2 const & p ) const { + return _v[0] * p._v[1] - _v[1] * p._v[0]; } + + inline S Sum() const { + return _v[0]+_v[1];} + + inline S Max() const { + return math::Max( _v[0], _v[1] ); } + + inline S Min() const { + return math::Min( _v[0], _v[1] ); } + + inline int MaxI() const { + return (_v[0] < _v[1]) ? 1:0; }; + + inline int MinI() const { + return (_v[0] > _v[1]) ? 1:0; }; + + inline PointType & Scale( const PointType & p ) { + _v[0] *= p._v[0]; _v[1] *= p._v[1]; return *this; } + + inline S StableDot ( const PointType & p ) const { + return _v[0]*p._v[0] +_v[1]*p._v[1]; } + //@} + +}; + +template +class Point3 : public Point<3,S> { +public: + typedef S ScalarType; + typedef Point3 PointType; + using Point<3,S>::_v; + using Point<3,S>::V; + using Point<3,S>::W; + + + //@{ + /** @name Special members for 3D points. **/ + + /// default + inline Point3 ():Point<3,S>(){} + /// yxz constructor + inline Point3 ( const S a, const S b, const S c){ + _v[0]=a; _v[1]=b; _v[2]=c; }; + + /// Cross product for 3D points + inline PointType operator ^ ( PointType const & p ) const { + return Point3 ( + _v[1]*p._v[2] - _v[2]*p._v[1], + _v[2]*p._v[0] - _v[0]*p._v[2], + _v[0]*p._v[1] - _v[1]*p._v[0] ); + } + //@} + + //@{ + /** @name Implementation of standard functions for 3D points **/ + + inline void Zero(){ + _v[0]=0; _v[1]=0; _v[2]=0; }; + + inline Point3 ( const S nv[3] ){ + _v[0]=nv[0]; _v[1]=nv[1]; _v[2]=nv[2]; }; + + inline Point3 operator + ( Point3 const & p) const{ + return Point3( _v[0]+p._v[0], _v[1]+p._v[1], _v[2]+p._v[2]); } + + inline Point3 operator - ( Point3 const & p) const { + return Point3( _v[0]-p._v[0], _v[1]-p._v[1], _v[2]-p._v[2]); } + + inline Point3 operator * ( const S s ) const { + return Point3( _v[0]*s, _v[1]*s , _v[2]*s ); } + + inline Point3 operator / ( const S s ) const { + S t=1.0/s; + return Point3( _v[0]*t, _v[1]*t , _v[2]*t ); } + + inline Point3 operator - () const { + return Point3 ( -_v[0], -_v[1] , -_v[2] ); } + + inline Point3 & operator += ( Point3 const & p ) { + _v[0] += p._v[0]; _v[1] += p._v[1]; _v[2] += p._v[2]; return *this; } + + inline Point3 & operator -= ( Point3 const & p ) { + _v[0] -= p._v[0]; _v[1] -= p._v[1]; _v[2] -= p._v[2]; return *this; } + + inline Point3 & operator *= ( const S s ) { + _v[0] *= s; _v[1] *= s; _v[2] *= s; return *this; } + + inline Point3 & operator /= ( const S s ) { + S t=1.0/s; _v[0] *= t; _v[1] *= t; _v[2] *= t; return *this; } + + inline S Norm() const { + return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] );} + + template static S Norm(const PT &p ) { + return math::Sqrt( p.V(0)*p.V(0) + p.V(1)*p.V(1) + p.V(2)*p.V(2) );} + + inline S SquaredNorm() const { + return ( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] );} + + template static S SquaredNorm(const PT &p ) { + return ( p.V(0)*p.V(0) + p.V(1)*p.V(1) + p.V(2)*p.V(2) );} + + inline S operator * ( PointType const & p ) const { + return ( _v[0]*p._v[0] + _v[1]*p._v[1] + _v[2]*p._v[2]) ; } + + inline bool operator == ( PointType const & p ) const { + return _v[0]==p._v[0] && _v[1]==p._v[1] && _v[2]==p._v[2] ;} + + inline bool operator != ( PointType const & p ) const { + return _v[0]!=p._v[0] || _v[1]!=p._v[1] || _v[2]!=p._v[2] ;} + + inline bool operator < ( PointType const & p ) const{ + return (_v[2]!=p._v[2])?(_v[2]< p._v[2]): + (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0] ( PointType const & p ) const { + return (_v[2]!=p._v[2])?(_v[2]> p._v[2]): + (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>p._v[0]); } + + inline bool operator <= ( PointType const & p ) { + return (_v[2]!=p._v[2])?(_v[2]< p._v[2]): + (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0]<=p._v[0]); } + + inline bool operator >= ( PointType const & p ) const { + return (_v[2]!=p._v[2])?(_v[2]> p._v[2]): + (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>=p._v[0]); } + + inline PointType & Normalize() { + S n = Norm(); + if(n!=0.0) { + n=S(1.0)/n; + _v[0]*=n; _v[1]*=n; _v[2]*=n; } + return *this;}; + + template PointType & Normalize(const PT &p){ + S n = Norm(); if(n!=0.0) { n=1.0/n; V(0)*=n; V(1)*=n; V(2)*=n; } + return *this;}; + + inline PointType & HomoNormalize(){ + if (_v[2]!=0.0) { _v[0] /= W(); _v[1] /= W(); W()=1.0; } + return *this;}; + + inline S NormInfinity() const { + return math::Max( math::Max( math::Abs(_v[0]), math::Abs(_v[1]) ), + math::Abs(_v[3]) ); } + + inline S NormOne() const { + return math::Abs(_v[0])+ math::Abs(_v[1])+math::Max(math::Abs(_v[2]));} + + inline S operator % ( PointType const & p ) const { + S t = (*this)*p; /* Area, general formula */ + return math::Sqrt( SquaredNorm() * p.SquaredNorm() - (t*t) );}; + + inline S Sum() const { + return _v[0]+_v[1]+_v[2];} + + inline S Max() const { + return math::Max( math::Max( _v[0], _v[1] ), _v[2] ); } + + inline S Min() const { + return math::Min( math::Min( _v[0], _v[1] ), _v[2] ); } + + inline int MaxI() const { + int i= (_v[0] < _v[1]) ? 1:0; if (_v[i] < _v[2]) i=2; return i;}; + + inline int MinI() const { + int i= (_v[0] > _v[1]) ? 1:0; if (_v[i] > _v[2]) i=2; return i;}; + + inline PointType & Scale( const PointType & p ) { + _v[0] *= p._v[0]; _v[1] *= p._v[1]; _v[2] *= p._v[2]; return *this; } + + inline S StableDot ( const PointType & p ) const { + S k0=_v[0]*p._v[0], k1=_v[1]*p._v[1], k2=_v[2]*p._v[2]; + int exp0,exp1,exp2; + frexp( double(k0), &exp0 ); + frexp( double(k1), &exp1 ); + frexp( double(k2), &exp2 ); + if( exp0 +class Point4 : public Point<4,S> { +public: + typedef S ScalarType; + typedef Point4 PointType; + using Point<3,S>::_v; + using Point<3,S>::V; + using Point<3,S>::W; + + //@{ + /** @name Special members for 4D points. **/ + /// default + inline Point4 (){} + + /// xyzw constructor + //@} + inline Point4 ( const S a, const S b, const S c, const S d){ + _v[0]=a; _v[1]=b; _v[2]=c; _v[3]=d; }; + //@{ + /** @name Implementation of standard functions for 3D points **/ + + inline void Zero(){ + _v[0]=0; _v[1]=0; _v[2]=0; _v[3]=0; }; + + inline Point4 ( const S nv[4] ){ + _v[0]=nv[0]; _v[1]=nv[1]; _v[2]=nv[2]; _v[3]=nv[3]; }; + + inline Point4 operator + ( Point4 const & p) const { + return Point4( _v[0]+p._v[0], _v[1]+p._v[1], _v[2]+p._v[2], _v[3]+p._v[3] ); } + + inline Point4 operator - ( Point4 const & p) const { + return Point4( _v[0]-p._v[0], _v[1]-p._v[1], _v[2]-p._v[2], _v[3]-p._v[3] ); } + + inline Point4 operator * ( const S s ) const { + return Point4( _v[0]*s, _v[1]*s , _v[2]*s , _v[3]*s ); } + + inline PointType operator ^ ( PointType const & p ) const { + assert(0); + return *this; + } + + inline Point4 operator / ( const S s ) const { + S t=1.0/s; + return Point4( _v[0]*t, _v[1]*t , _v[2]*t , _v[3]*t ); } + + inline Point4 operator - () const { + return Point4 ( -_v[0], -_v[1] , -_v[2] , -_v[3] ); } + + inline Point4 & operator += ( Point4 const & p ) { + _v[0] += p._v[0]; _v[1] += p._v[1]; _v[2] += p._v[2]; _v[3] += p._v[3]; return *this; } + + inline Point4 & operator -= ( Point4 const & p ) { + _v[0] -= p._v[0]; _v[1] -= p._v[1]; _v[2] -= p._v[2]; _v[3] -= p._v[3]; return *this; } + + inline Point4 & operator *= ( const S s ) { + _v[0] *= s; _v[1] *= s; _v[2] *= s; _v[3] *= s; return *this; } + + inline Point4 & operator /= ( const S s ) { + S t=1.0/s; _v[0] *= t; _v[1] *= t; _v[2] *= t; _v[3] *= t; return *this; } + + inline S Norm() const { + return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3] );} + + template static S Norm(const PT &p ) { + return math::Sqrt( p.V(0)*p.V(0) + p.V(1)*p.V(1) + p.V(2)*p.V(2) + p.V(3)*p.V(3) );} + + inline S SquaredNorm() const { + return ( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3] );} + + template static S SquaredNorm(const PT &p ) { + return ( p.V(0)*p.V(0) + p.V(1)*p.V(1) + p.V(2)*p.V(2) + p.V(3)*p.V(3) );} + + inline S operator * ( PointType const & p ) const { + return ( _v[0]*p._v[0] + _v[1]*p._v[1] + _v[2]*p._v[2] + _v[3]*p._v[3] ); } + + inline bool operator == ( PointType const & p ) const { + return _v[0]==p._v[0] && _v[1]==p._v[1] && _v[2]==p._v[2] && _v[3]==p._v[3];} + + inline bool operator != ( PointType const & p ) const { + return _v[0]!=p._v[0] || _v[1]!=p._v[1] || _v[2]!=p._v[2] || _v[3]!=p._v[3];} + + inline bool operator < ( PointType const & p ) const{ + return (_v[3]!=p._v[3])?(_v[3]< p._v[3]) : (_v[2]!=p._v[2])?(_v[2]< p._v[2]): + (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0] ( PointType const & p ) const { + return (_v[3]!=p._v[3])?(_v[3]> p._v[3]) : (_v[2]!=p._v[2])?(_v[2]> p._v[2]): + (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>p._v[0]); } + + inline bool operator <= ( PointType const & p ) { + return (_v[3]!=p._v[3])?(_v[3]< p._v[3]) : (_v[2]!=p._v[2])?(_v[2]< p._v[2]): + (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0]<=p._v[0]); } + + inline bool operator >= ( PointType const & p ) const { + return (_v[3]!=p._v[3])?(_v[3]> p._v[3]) : (_v[2]!=p._v[2])?(_v[2]> p._v[2]): + (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>=p._v[0]); } + + inline PointType & Normalize() { + PointType n = Norm(); if(n!=0.0) { n=1.0/n; _v[0]*=n; _v[1]*=n; _v[2]*=n; _v[3]*=n; } + return *this;}; + + template PointType & Normalize(const PT &p){ + PointType n = Norm(); if(n!=0.0) { n=1.0/n; V(0)*=n; V(1)*=n; V(2)*=n; V(3)*=n; } + return *this;}; + + inline PointType & HomoNormalize(){ + if (_v[3]!=0.0) { _v[0] /= W(); _v[1] /= W(); _v[2] /= W(); W()=1.0; } + return *this;}; + + inline S NormInfinity() const { + return math::Max( math::Max( math::Abs(_v[0]), math::Abs(_v[1]) ), + math::Max( math::Abs(_v[2]), math::Abs(_v[3]) ) ); } + + inline S NormOne() const { + return math::Abs(_v[0])+ math::Abs(_v[1])+math::Max(math::Abs(_v[2]),math::Abs(_v[3]));} + + inline S operator % ( PointType const & p ) const { + S t = (*this)*p; /* Area, general formula */ + return math::Sqrt( SquaredNorm() * p.SquaredNorm() - (t*t) );}; + + inline S Sum() const { + return _v[0]+_v[1]+_v[2]+_v[3];} + + inline S Max() const { + return math::Max( math::Max( _v[0], _v[1] ), math::Max( _v[2], _v[3] )); } + + inline S Min() const { + return math::Min( math::Min( _v[0], _v[1] ), math::Min( _v[2], _v[3] )); } + + inline int MaxI() const { + int i= (_v[0] < _v[1]) ? 1:0; if (_v[i] < _v[2]) i=2; if (_v[i] < _v[3]) i=3; + return i;}; + + inline int MinI() const { + int i= (_v[0] > _v[1]) ? 1:0; if (_v[i] > _v[2]) i=2; if (_v[i] > _v[3]) i=3; + return i;}; + + inline PointType & Scale( const PointType & p ) { + _v[0] *= p._v[0]; _v[1] *= p._v[1]; _v[2] *= p._v[2]; _v[3] *= p._v[3]; return *this; } + + inline S StableDot ( const PointType & p ) const { + S k0=_v[0]*p._v[0], k1=_v[1]*p._v[1], k2=_v[2]*p._v[2], k3=_v[3]*p._v[3]; + int exp0,exp1,exp2,exp3; + frexp( double(k0), &exp0 );frexp( double(k1), &exp1 ); + frexp( double(k2), &exp2 );frexp( double(k3), &exp3 ); + if (exp0>exp1) { math::Swap(k0,k1); math::Swap(exp0,exp1); } + if (exp2>exp3) { math::Swap(k2,k3); math::Swap(exp2,exp3); } + if (exp0>exp2) { math::Swap(k0,k2); math::Swap(exp0,exp2); } + if (exp1>exp3) { math::Swap(k1,k3); math::Swap(exp1,exp3); } + if (exp2>exp3) { math::Swap(k2,k3); math::Swap(exp2,exp3); } + return ( (k0 + k1) + k2 ) +k3; } + + //@} +}; + + +template +inline S Angle( Point3 const & p1, Point3 const & p2 ) +{ + S w = p1.Norm()*p2.Norm(); + if(w==0) return -1; + S t = (p1*p2)/w; + if(t>1) t = 1; + else if(t<-1) t = -1; + return (S) acos(t); +} + +// versione uguale alla precedente ma che assume che i due vettori siano unitari +template +inline S AngleN( Point3 const & p1, Point3 const & p2 ) +{ + S w = p1*p2; + if(w>1) + w = 1; + else if(w<-1) + w=-1; + return (S) acos(w); +} + + +template +inline S Norm( Point const & p ) +{ + return p.Norm(); +} + +template +inline S SquaredNorm( Point const & p ) +{ + return p.SquaredNorm(); +} + +template +inline Point & Normalize( Point & p ) +{ + p.Normalize(); + return p; +} + +template +inline S Distance( Point const & p1,Point const & p2 ) +{ + return (p1-p2).Norm(); +} + +template +inline S SquaredDistance( Point const & p1,Point const & p2 ) +{ + return (p1-p2).SquaredNorm(); +} + + +//template +//struct Point2:public Point<2,S>{ +// inline Point2(){}; +// inline Point2(Point<2,S> const & p):Point<2,S>(p){} ; +// inline Point2( const S a, const S b):Point<2,S>(a,b){}; +//}; +// +//template +//struct Point3:public Point3 { +// inline Point3(){}; +// inline Point3(Point3 const & p):Point3 (p){} +// inline Point3( const S a, const S b, const S c):Point3 (a,b,c){}; +//}; +// +// +//template +//struct Point4:public Point4{ +// inline Point4(){}; +// inline Point4(Point4 const & p):Point4(p){} +// inline Point4( const S a, const S b, const S c, const S d):Point4(a,b,c,d){}; +//}; + +typedef Point2 Point2s; +typedef Point2 Point2i; +typedef Point2 Point2f; +typedef Point2 Point2d; +typedef Point2 Vector2s; +typedef Point2 Vector2i; +typedef Point2 Vector2f; +typedef Point2 Vector2d; + +typedef Point3 Point3s; +typedef Point3 Point3i; +typedef Point3 Point3f; +typedef Point3 Point3d; +typedef Point3 Vector3s; +typedef Point3 Vector3i; +typedef Point3 Vector3f; +typedef Point3 Vector3d; + + +typedef Point4 Point4s; +typedef Point4 Point4i; +typedef Point4 Point4f; +typedef Point4 Point4d; +typedef Point4 Vector4s; +typedef Point4 Vector4i; +typedef Point4 Vector4f; +typedef Point4 Vector4d; + +/*@}*/ + +//added only for backward compatibility +template +struct PointBase : Point +{ + PointBase() + :Point() + { + } +}; + +} // end namespace ndim +} // end namespace vcg +#endif + diff --git a/vcg/space/intersection3.h b/vcg/space/intersection3.h index 9890759f..f744846a 100644 --- a/vcg/space/intersection3.h +++ b/vcg/space/intersection3.h @@ -404,16 +404,17 @@ namespace vcg { /// intersection between two triangles template - inline bool Intersection_(const TRIANGLETYPE & t0,const TRIANGLETYPE & t1){ + inline bool Intersection(const TRIANGLETYPE & t0,const TRIANGLETYPE & t1){ return NoDivTriTriIsect(t0.P0(0),t0.P0(1),t0.P0(2), t1.P0(0),t1.P0(1),t1.P0(2)); } + template inline bool Intersection(Point3 V0,Point3 V1,Point3 V2, Point3 U0,Point3 U1,Point3 U2){ return NoDivTriTriIsect(V0,V1,V2,U0,U1,U2); } - +#if 0 template inline bool Intersection(Point3 V0,Point3 V1,Point3 V2, Point3 U0,Point3 U1,Point3 U2,int *coplanar, @@ -528,7 +529,8 @@ bool Intersection( const Ray3 & ray, const Point3 & vert0, return true; } - +#endif +#if 0 // ray-triangle, gives intersection 3d point and distance along ray template bool Intersection( const Line3 & ray, const Point3 & vert0, @@ -577,7 +579,7 @@ bool Intersection( const Line3 & ray, const Point3 & vert0, inte = vert0 + edge1*a + edge2*b; return true; } - +#endif // line-box template bool Intersection_Line_Box( const Box3 & box, const Line3 & r, Point3 & coord ) diff --git a/vcg/space/point.h b/vcg/space/point.h index 9fb74eff..13f0912c 100644 --- a/vcg/space/point.h +++ b/vcg/space/point.h @@ -20,92 +20,73 @@ * for more details. * * * ****************************************************************************/ -/**************************************************************************** - History -$Log: not supported by cvs2svn $ -Revision 1.9 2006/12/20 15:23:52 ganovelli -using of locally defined variable removed - -Revision 1.8 2006/04/11 08:10:05 zifnab1974 -changes necessary for gcc 3.4.5 on linux 64bit. - -Revision 1.7 2005/12/12 11:22:32 ganovelli -compiled with gcc - -Revision 1.6 2005/01/12 11:25:52 ganovelli -corrected Point<3 - -Revision 1.5 2004/10/20 16:45:21 ganovelli -first compiling version (MC,INtel,gcc) - -Revision 1.4 2004/04/29 10:47:06 ganovelli -some siyntax error corrected - -Revision 1.3 2004/04/05 12:36:43 tarini -unified version: PointBase version, with no guards "(N==3)" - - - -Revision 1.1 2004/03/16 03:07:38 tarini -"dimensionally unified" version: first commit - -****************************************************************************/ +#ifndef VCG_USE_EIGEN +#include "deprecated_point.h" +#else #ifndef __VCGLIB_POINT #define __VCGLIB_POINT -#include +#include "../math/eigen.h" #include #include +namespace vcg{ +template class Point4; +} + +namespace Eigen{ +template +struct ei_traits > : ei_traits > {}; +} + namespace vcg { +namespace ndim{ - namespace ndim{ - - -//template -//class Point; /** \addtogroup space */ /*@{*/ - /** - The templated class for representing a point in R^N space. - The class is templated over the ScalarType class that is used to represent coordinates. - PointBase provides the interface and the common operators for points - of any dimensionality. - */ - -template -class Point +/** + The templated class for representing a point in R^N space. + The class is templated over the ScalarType class that is used to represent coordinates. + PointBase provides the interface and the common operators for points + of any dimensionality. + */ +template class Point : public Eigen::Matrix { + typedef Eigen::Matrix _Base; + using _Base::coeff; + using _Base::coeffRef; + using _Base::setZero; + using _Base::data; + using _Base::V; + public: - typedef S ScalarType; + + _EIGEN_GENERIC_PUBLIC_INTERFACE(Point,_Base); + + typedef S ScalarType; typedef VoidType ParamType; typedef Point PointType; - enum {Dimension=N}; + enum {Dimension = N}; - -protected: - /// The only data member. Hidden to user. - S _v[N]; - -public: + VCG_EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Point) //@{ - /** @name Standard Constructors and Initializers - No casting operators have been introduced to avoid automatic unattended (and costly) conversion between different PointType types - **/ - - inline Point () { }; -// inline Point ( const S nv[N] ); - + /** @name Standard Constructors and Initializers + No casting operators have been introduced to avoid automatic unattended (and costly) conversion between different PointType types + **/ + inline Point() : Base() {} + template + inline Point(const Eigen::MatrixBase& other) : Base(other) {} + /// Padding function: give a default 0 value to all the elements that are not in the [0..2] range. /// Useful for managing in a consistent way object that could have point2 / point3 / point4 inline S Ext( const int i ) const { - if(i>=0 && i<=N) return _v[i]; + if(i>=0 && i<=N) return data()[i]; else return 0; } @@ -113,10 +94,10 @@ public: template inline void Import( const Point & b ) { - _v[0] = ScalarType(b[0]); - _v[1] = ScalarType(b[1]); - if (N>2) { if (N2>2) _v[2] = ScalarType(b[2]); else _v[2] = 0;}; - if (N>3) { if (N2>3) _v[3] = ScalarType(b[3]); else _v[3] = 0;}; + data()[0] = ScalarType(b[0]); + data()[1] = ScalarType(b[1]); + if (N>2) { if (N2>2) data()[2] = ScalarType(b[2]); else data()[2] = 0;}; + if (N>3) { if (N2>3) data()[3] = ScalarType(b[3]); else data()[3] = 0;}; } /// constructor for points with different scalar type and-or dimensionality @@ -131,10 +112,10 @@ public: template inline void ImportHomo( const Point & b ) { - _v[0] = ScalarType(b[0]); - _v[1] = ScalarType(b[1]); - if (N>2) { _v[2] = ScalarType(_v[2]); }; - _v[N-1] = 1.0; + data()[0] = ScalarType(b[0]); + data()[1] = ScalarType(b[1]); + if (N>2) { data()[2] = ScalarType(data()[2]); }; + data()[N-1] = 1.0; } /// constructor for homogeneus point. @@ -152,128 +133,24 @@ public: /** @name Data Access. access to data is done by overloading of [] or explicit naming of coords (x,y,z)**/ - inline S & operator [] ( const int i ) - { - assert(i>=0 && i=0 && i2); return _v[2]; } + inline const S &X() const { return data()[0]; } + inline const S &Y() const { return data()[1]; } + inline const S &Z() const { static_assert(N>2); return data()[2]; } /// W is in any case the last coordinate. /// (in a 2D point, W() == Y(). In a 3D point, W()==Z() /// in a 4D point, W() is a separate component) - inline const S &W() const { return _v[N-1]; } - inline S &X() { return _v[0]; } - inline S &Y() { return _v[1]; } - inline S &Z() { static_assert(N>2); return _v[2]; } - inline S &W() { return _v[N-1]; } - inline const S * V() const - { - return _v; - } - inline S & V( const int i ) - { - assert(i>=0 && i=0 && i2); return data()[2]; } + inline S &W() { return data()[N-1]; } //@} -//@{ - /** @name Linearity for points - **/ - /// sets a PointType to Zero - inline void SetZero() - { - for(unsigned int ii = 0; ii < Dimension;++ii) - V(ii) = S(); - } - - inline PointType operator + ( PointType const & p) const - { - PointType res; - for(unsigned int ii = 0; ii < Dimension;++ii) - res[ii] = V(ii) + p[ii]; - return res; - } - - inline PointType operator - ( PointType const & p) const - { - PointType res; - for(unsigned int ii = 0; ii < Dimension;++ii) - res[ii] = V(ii) - p[ii]; - return res; - } - - inline PointType operator * ( const S s ) const - { - PointType res; - for(unsigned int ii = 0; ii < Dimension;++ii) - res[ii] = V(ii) * s; - return res; - } - - inline PointType operator / ( const S s ) const - { - PointType res; - for(unsigned int ii = 0; ii < Dimension;++ii) - res[ii] = V(ii) / s; - return res; - } - - inline PointType & operator += ( PointType const & p) - { - for(unsigned int ii = 0; ii < Dimension;++ii) - V(ii) += p[ii]; - return *this; - } - - inline PointType & operator -= ( PointType const & p) - { - for(unsigned int ii = 0; ii < Dimension;++ii) - V(ii) -= p[ii]; - return *this; - } - - inline PointType & operator *= ( const S s ) - { - for(unsigned int ii = 0; ii < Dimension;++ii) - V(ii) *= s; - return *this; - } - - inline PointType & operator /= ( const S s ) - { - for(unsigned int ii = 0; ii < Dimension;++ii) - V(ii) *= s; - return *this; - } - - inline PointType operator - () const - { - PointType res; - for(unsigned int ii = 0; ii < Dimension;++ii) - res[ii] = - V(ii); - return res; - } -//@} //@{ /** @name Dot products (cross product "%" is defined olny for 3D points) **/ - /// Dot product - inline S operator * ( PointType const & p ) const; /// slower version, more stable (double precision only) inline S StableDot ( const PointType & p ) const; @@ -285,53 +162,25 @@ public: /** @name Norms **/ - /// Euclidean norm - inline S Norm() const; /// Euclidean norm, static version template static S Norm(const PT &p ); - /// Squared Euclidean norm - inline S SquaredNorm() const; /// Squared Euclidean norm, static version template static S SquaredNorm(const PT &p ); - /// Normalization (division by norm) - inline PointType & Normalize(); /// Normalization (division by norm), static version template static PointType & Normalize(const PT &p); - /// Homogeneous normalization (division by W) - inline PointType & HomoNormalize(); - - /// norm infinity: largest absolute value of compoenet - inline S NormInfinity() const; - /// norm 1: sum of absolute values of components - inline S NormOne() const; //@} + /// Signed area operator /// a % b returns the signed area of the parallelogram inside a and b - inline S operator % ( PointType const & p ) const; - - /// the sum of the components - inline S Sum() const; - /// returns the biggest component - inline S Max() const; - /// returns the smallest component - inline S Min() const; - /// returns the index of the biggest component - inline int MaxI() const; - /// returns the index of the smallest component - inline int MinI() const; - - - /// Per component scaling - inline PointType & Scale( const PointType & p ); - + // inline S operator % ( PointType const & p ) const; /// Convert to polar coordinates void ToPolar( S & ro, S & tetha, S & fi ) const { ro = Norm(); - tetha = (S)atan2( _v[1], _v[0] ); - fi = (S)acos( _v[2]/ro ); + tetha = (S)atan2( data()[1], data()[0] ); + fi = (S)acos( data()[2]/ro ); } //@{ @@ -355,626 +204,78 @@ public: (provided for uniformity with other spatial classes. trivial for points) **/ - inline PointType LocalToGlobal(ParamType p) const{ - return *this; } - - inline ParamType GlobalToLocal(PointType p) const{ - ParamType p(); return p; } + inline PointType LocalToGlobal(ParamType p) const { return *this; } + inline ParamType GlobalToLocal(PointType p) const { ParamType p(); return p; } //@} }; // end class definition +// workaround the lack of template typedef (the next c++ standard will support them :) ) - - - - - - -template -class Point2 : public Point<2,S> { -public: - typedef S ScalarType; - typedef Point2 PointType; - using Point<2,S>::_v; - using Point<2,S>::V; - using Point<2,S>::W; - - //@{ - /** @name Special members for 2D points. **/ - - /// default - inline Point2 (){} - - /// yx constructor - inline Point2 ( const S a, const S b){ - _v[0]=a; _v[1]=b; }; - - /// unary orthogonal operator (2D equivalent of cross product) - /// returns orthogonal vector (90 deg left) - inline Point2 operator ~ () const { - return Point2 ( -_v[2], _v[1] ); - } - - /// returns the angle with X axis (radiants, in [-PI, +PI] ) - inline ScalarType &Angle(){ - return math::Atan2(_v[1],_v[0]);} - - /// transform the point in cartesian coords into polar coords - inline Point2 & ToPolar(){ - ScalarType t = Angle(); - _v[0] = Norm(); - _v[1] = t; - return *this;} - - /// transform the point in polar coords into cartesian coords - inline Point2 & ToCartesian() { - ScalarType l = _v[0]; - _v[0] = (ScalarType)(l*math::Cos(_v[1])); - _v[1] = (ScalarType)(l*math::Sin(_v[1])); - return *this;} - - /// rotates the point of an angle (radiants, counterclockwise) - inline Point2 & Rotate( const ScalarType rad ){ - ScalarType t = _v[0]; - ScalarType s = math::Sin(rad); - ScalarType c = math::Cos(rad); - _v[0] = _v[0]*c - _v[1]*s; - _v[1] = t *s + _v[1]*c; - return *this;} - - //@} - - //@{ - /** @name Implementation of standard functions for 3D points **/ - - inline void Zero(){ - _v[0]=0; _v[1]=0; }; - - inline Point2 ( const S nv[2] ){ - _v[0]=nv[0]; _v[1]=nv[1]; }; - - inline Point2 operator + ( Point2 const & p) const { - return Point2( _v[0]+p._v[0], _v[1]+p._v[1]); } - - inline Point2 operator - ( Point2 const & p) const { - return Point2( _v[0]-p._v[0], _v[1]-p._v[1]); } - - inline Point2 operator * ( const S s ) const { - return Point2( _v[0]*s, _v[1]*s ); } - - inline Point2 operator / ( const S s ) const { - S t=1.0/s; - return Point2( _v[0]*t, _v[1]*t ); } - - inline Point2 operator - () const { - return Point2 ( -_v[0], -_v[1] ); } - - inline Point2 & operator += ( Point2 const & p ) { - _v[0] += p._v[0]; _v[1] += p._v[1]; return *this; } - - inline Point2 & operator -= ( Point2 const & p ) { - _v[0] -= p._v[0]; _v[1] -= p._v[1]; return *this; } - - inline Point2 & operator *= ( const S s ) { - _v[0] *= s; _v[1] *= s; return *this; } - - inline Point2 & operator /= ( const S s ) { - S t=1.0/s; _v[0] *= t; _v[1] *= t; return *this; } - - inline S Norm() const { - return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] );} - - template static S Norm(const PT &p ) { - return math::Sqrt( p.V(0)*p.V(0) + p.V(1)*p.V(1) );} - - inline S SquaredNorm() const { - return ( _v[0]*_v[0] + _v[1]*_v[1] );} - - template static S SquaredNorm(const PT &p ) { - return ( p.V(0)*p.V(0) + p.V(1)*p.V(1) );} - - inline S operator * ( Point2 const & p ) const { - return ( _v[0]*p._v[0] + _v[1]*p._v[1]) ; } - - inline bool operator == ( Point2 const & p ) const { - return _v[0]==p._v[0] && _v[1]==p._v[1] ;} - - inline bool operator != ( Point2 const & p ) const { - return _v[0]!=p._v[0] || _v[1]!=p._v[1] ;} - - inline bool operator < ( Point2 const & p ) const{ - return (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0] ( Point2 const & p ) const { - return (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>p._v[0]); } - - inline bool operator <= ( Point2 const & p ) { - return (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0]<=p._v[0]); } - - inline bool operator >= ( Point2 const & p ) const { - return (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>=p._v[0]); } - - inline Point2 & Normalize() { - PointType n = Norm(); if(n!=0.0) { n=1.0/n; _v[0]*=n; _v[1]*=n;} return *this;}; - - template Point2 & Normalize(const PT &p){ - PointType n = Norm(); if(n!=0.0) { n=1.0/n; V(0)*=n; V(1)*=n; } - return *this;}; - - inline Point2 & HomoNormalize(){ - if (_v[2]!=0.0) { _v[0] /= W(); W()=1.0; } return *this;}; - - inline S NormInfinity() const { - return math::Max( math::Abs(_v[0]), math::Abs(_v[1]) ); } - - inline S NormOne() const { - return math::Abs(_v[0])+ math::Abs(_v[1]);} - - inline S operator % ( Point2 const & p ) const { - return _v[0] * p._v[1] - _v[1] * p._v[0]; } - - inline S Sum() const { - return _v[0]+_v[1];} - - inline S Max() const { - return math::Max( _v[0], _v[1] ); } - - inline S Min() const { - return math::Min( _v[0], _v[1] ); } - - inline int MaxI() const { - return (_v[0] < _v[1]) ? 1:0; }; - - inline int MinI() const { - return (_v[0] > _v[1]) ? 1:0; }; - - inline PointType & Scale( const PointType & p ) { - _v[0] *= p._v[0]; _v[1] *= p._v[1]; return *this; } - - inline S StableDot ( const PointType & p ) const { - return _v[0]*p._v[0] +_v[1]*p._v[1]; } - //@} - +template +struct Point2:public Point<2,S>{ + typedef Point<3,S> Base; + inline Point2() : Base() {}; + inline Point2(const Point2& p):Base(p){}; + inline Point2(S a, S b):Base(a,b){}; + template + inline Point2(const Eigen::MatrixBase& other) : Base(other) {} }; template -class Point3 : public Point<3,S> { -public: - typedef S ScalarType; - typedef Point3 PointType; - using Point<3,S>::_v; - using Point<3,S>::V; - using Point<3,S>::W; - - - //@{ - /** @name Special members for 3D points. **/ - - /// default - inline Point3 ():Point<3,S>(){} - /// yxz constructor - inline Point3 ( const S a, const S b, const S c){ - _v[0]=a; _v[1]=b; _v[2]=c; }; - - /// Cross product for 3D points - inline PointType operator ^ ( PointType const & p ) const { - return Point3 ( - _v[1]*p._v[2] - _v[2]*p._v[1], - _v[2]*p._v[0] - _v[0]*p._v[2], - _v[0]*p._v[1] - _v[1]*p._v[0] ); - } - //@} - - //@{ - /** @name Implementation of standard functions for 3D points **/ - - inline void Zero(){ - _v[0]=0; _v[1]=0; _v[2]=0; }; - - inline Point3 ( const S nv[3] ){ - _v[0]=nv[0]; _v[1]=nv[1]; _v[2]=nv[2]; }; - - inline Point3 operator + ( Point3 const & p) const{ - return Point3( _v[0]+p._v[0], _v[1]+p._v[1], _v[2]+p._v[2]); } - - inline Point3 operator - ( Point3 const & p) const { - return Point3( _v[0]-p._v[0], _v[1]-p._v[1], _v[2]-p._v[2]); } - - inline Point3 operator * ( const S s ) const { - return Point3( _v[0]*s, _v[1]*s , _v[2]*s ); } - - inline Point3 operator / ( const S s ) const { - S t=1.0/s; - return Point3( _v[0]*t, _v[1]*t , _v[2]*t ); } - - inline Point3 operator - () const { - return Point3 ( -_v[0], -_v[1] , -_v[2] ); } - - inline Point3 & operator += ( Point3 const & p ) { - _v[0] += p._v[0]; _v[1] += p._v[1]; _v[2] += p._v[2]; return *this; } - - inline Point3 & operator -= ( Point3 const & p ) { - _v[0] -= p._v[0]; _v[1] -= p._v[1]; _v[2] -= p._v[2]; return *this; } - - inline Point3 & operator *= ( const S s ) { - _v[0] *= s; _v[1] *= s; _v[2] *= s; return *this; } - - inline Point3 & operator /= ( const S s ) { - S t=1.0/s; _v[0] *= t; _v[1] *= t; _v[2] *= t; return *this; } - - inline S Norm() const { - return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] );} - - template static S Norm(const PT &p ) { - return math::Sqrt( p.V(0)*p.V(0) + p.V(1)*p.V(1) + p.V(2)*p.V(2) );} - - inline S SquaredNorm() const { - return ( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] );} - - template static S SquaredNorm(const PT &p ) { - return ( p.V(0)*p.V(0) + p.V(1)*p.V(1) + p.V(2)*p.V(2) );} - - inline S operator * ( PointType const & p ) const { - return ( _v[0]*p._v[0] + _v[1]*p._v[1] + _v[2]*p._v[2]) ; } - - inline bool operator == ( PointType const & p ) const { - return _v[0]==p._v[0] && _v[1]==p._v[1] && _v[2]==p._v[2] ;} - - inline bool operator != ( PointType const & p ) const { - return _v[0]!=p._v[0] || _v[1]!=p._v[1] || _v[2]!=p._v[2] ;} - - inline bool operator < ( PointType const & p ) const{ - return (_v[2]!=p._v[2])?(_v[2]< p._v[2]): - (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0] ( PointType const & p ) const { - return (_v[2]!=p._v[2])?(_v[2]> p._v[2]): - (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>p._v[0]); } - - inline bool operator <= ( PointType const & p ) { - return (_v[2]!=p._v[2])?(_v[2]< p._v[2]): - (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0]<=p._v[0]); } - - inline bool operator >= ( PointType const & p ) const { - return (_v[2]!=p._v[2])?(_v[2]> p._v[2]): - (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>=p._v[0]); } - - inline PointType & Normalize() { - S n = Norm(); - if(n!=0.0) { - n=S(1.0)/n; - _v[0]*=n; _v[1]*=n; _v[2]*=n; } - return *this;}; - - template PointType & Normalize(const PT &p){ - S n = Norm(); if(n!=0.0) { n=1.0/n; V(0)*=n; V(1)*=n; V(2)*=n; } - return *this;}; - - inline PointType & HomoNormalize(){ - if (_v[2]!=0.0) { _v[0] /= W(); _v[1] /= W(); W()=1.0; } - return *this;}; - - inline S NormInfinity() const { - return math::Max( math::Max( math::Abs(_v[0]), math::Abs(_v[1]) ), - math::Abs(_v[3]) ); } - - inline S NormOne() const { - return math::Abs(_v[0])+ math::Abs(_v[1])+math::Max(math::Abs(_v[2]));} - - inline S operator % ( PointType const & p ) const { - S t = (*this)*p; /* Area, general formula */ - return math::Sqrt( SquaredNorm() * p.SquaredNorm() - (t*t) );}; - - inline S Sum() const { - return _v[0]+_v[1]+_v[2];} - - inline S Max() const { - return math::Max( math::Max( _v[0], _v[1] ), _v[2] ); } - - inline S Min() const { - return math::Min( math::Min( _v[0], _v[1] ), _v[2] ); } - - inline int MaxI() const { - int i= (_v[0] < _v[1]) ? 1:0; if (_v[i] < _v[2]) i=2; return i;}; - - inline int MinI() const { - int i= (_v[0] > _v[1]) ? 1:0; if (_v[i] > _v[2]) i=2; return i;}; - - inline PointType & Scale( const PointType & p ) { - _v[0] *= p._v[0]; _v[1] *= p._v[1]; _v[2] *= p._v[2]; return *this; } - - inline S StableDot ( const PointType & p ) const { - S k0=_v[0]*p._v[0], k1=_v[1]*p._v[1], k2=_v[2]*p._v[2]; - int exp0,exp1,exp2; - frexp( double(k0), &exp0 ); - frexp( double(k1), &exp1 ); - frexp( double(k2), &exp2 ); - if( exp0 { + typedef Point<3,S> Base; + inline Point3() : Base() {}; + inline Point3(const Point3& p):Base(p){} + inline Point3(S a, S b, S c):Base(a,b,c){}; + template + inline Point3(const Eigen::MatrixBase& other) : Base(other) {} }; + template -class Point4 : public Point<4,S> { -public: - typedef S ScalarType; - typedef Point4 PointType; - using Point<3,S>::_v; - using Point<3,S>::V; - using Point<3,S>::W; - - //@{ - /** @name Special members for 4D points. **/ - /// default - inline Point4 (){} - - /// xyzw constructor - //@} - inline Point4 ( const S a, const S b, const S c, const S d){ - _v[0]=a; _v[1]=b; _v[2]=c; _v[3]=d; }; - //@{ - /** @name Implementation of standard functions for 3D points **/ - - inline void Zero(){ - _v[0]=0; _v[1]=0; _v[2]=0; _v[3]=0; }; - - inline Point4 ( const S nv[4] ){ - _v[0]=nv[0]; _v[1]=nv[1]; _v[2]=nv[2]; _v[3]=nv[3]; }; - - inline Point4 operator + ( Point4 const & p) const { - return Point4( _v[0]+p._v[0], _v[1]+p._v[1], _v[2]+p._v[2], _v[3]+p._v[3] ); } - - inline Point4 operator - ( Point4 const & p) const { - return Point4( _v[0]-p._v[0], _v[1]-p._v[1], _v[2]-p._v[2], _v[3]-p._v[3] ); } - - inline Point4 operator * ( const S s ) const { - return Point4( _v[0]*s, _v[1]*s , _v[2]*s , _v[3]*s ); } - - inline PointType operator ^ ( PointType const & p ) const { - assert(0); - return *this; - } - - inline Point4 operator / ( const S s ) const { - S t=1.0/s; - return Point4( _v[0]*t, _v[1]*t , _v[2]*t , _v[3]*t ); } - - inline Point4 operator - () const { - return Point4 ( -_v[0], -_v[1] , -_v[2] , -_v[3] ); } - - inline Point4 & operator += ( Point4 const & p ) { - _v[0] += p._v[0]; _v[1] += p._v[1]; _v[2] += p._v[2]; _v[3] += p._v[3]; return *this; } - - inline Point4 & operator -= ( Point4 const & p ) { - _v[0] -= p._v[0]; _v[1] -= p._v[1]; _v[2] -= p._v[2]; _v[3] -= p._v[3]; return *this; } - - inline Point4 & operator *= ( const S s ) { - _v[0] *= s; _v[1] *= s; _v[2] *= s; _v[3] *= s; return *this; } - - inline Point4 & operator /= ( const S s ) { - S t=1.0/s; _v[0] *= t; _v[1] *= t; _v[2] *= t; _v[3] *= t; return *this; } - - inline S Norm() const { - return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3] );} - - template static S Norm(const PT &p ) { - return math::Sqrt( p.V(0)*p.V(0) + p.V(1)*p.V(1) + p.V(2)*p.V(2) + p.V(3)*p.V(3) );} - - inline S SquaredNorm() const { - return ( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3] );} - - template static S SquaredNorm(const PT &p ) { - return ( p.V(0)*p.V(0) + p.V(1)*p.V(1) + p.V(2)*p.V(2) + p.V(3)*p.V(3) );} - - inline S operator * ( PointType const & p ) const { - return ( _v[0]*p._v[0] + _v[1]*p._v[1] + _v[2]*p._v[2] + _v[3]*p._v[3] ); } - - inline bool operator == ( PointType const & p ) const { - return _v[0]==p._v[0] && _v[1]==p._v[1] && _v[2]==p._v[2] && _v[3]==p._v[3];} - - inline bool operator != ( PointType const & p ) const { - return _v[0]!=p._v[0] || _v[1]!=p._v[1] || _v[2]!=p._v[2] || _v[3]!=p._v[3];} - - inline bool operator < ( PointType const & p ) const{ - return (_v[3]!=p._v[3])?(_v[3]< p._v[3]) : (_v[2]!=p._v[2])?(_v[2]< p._v[2]): - (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0] ( PointType const & p ) const { - return (_v[3]!=p._v[3])?(_v[3]> p._v[3]) : (_v[2]!=p._v[2])?(_v[2]> p._v[2]): - (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>p._v[0]); } - - inline bool operator <= ( PointType const & p ) { - return (_v[3]!=p._v[3])?(_v[3]< p._v[3]) : (_v[2]!=p._v[2])?(_v[2]< p._v[2]): - (_v[1]!=p._v[1])?(_v[1]< p._v[1]) : (_v[0]<=p._v[0]); } - - inline bool operator >= ( PointType const & p ) const { - return (_v[3]!=p._v[3])?(_v[3]> p._v[3]) : (_v[2]!=p._v[2])?(_v[2]> p._v[2]): - (_v[1]!=p._v[1])?(_v[1]> p._v[1]) : (_v[0]>=p._v[0]); } - - inline PointType & Normalize() { - PointType n = Norm(); if(n!=0.0) { n=1.0/n; _v[0]*=n; _v[1]*=n; _v[2]*=n; _v[3]*=n; } - return *this;}; - - template PointType & Normalize(const PT &p){ - PointType n = Norm(); if(n!=0.0) { n=1.0/n; V(0)*=n; V(1)*=n; V(2)*=n; V(3)*=n; } - return *this;}; - - inline PointType & HomoNormalize(){ - if (_v[3]!=0.0) { _v[0] /= W(); _v[1] /= W(); _v[2] /= W(); W()=1.0; } - return *this;}; - - inline S NormInfinity() const { - return math::Max( math::Max( math::Abs(_v[0]), math::Abs(_v[1]) ), - math::Max( math::Abs(_v[2]), math::Abs(_v[3]) ) ); } - - inline S NormOne() const { - return math::Abs(_v[0])+ math::Abs(_v[1])+math::Max(math::Abs(_v[2]),math::Abs(_v[3]));} - - inline S operator % ( PointType const & p ) const { - S t = (*this)*p; /* Area, general formula */ - return math::Sqrt( SquaredNorm() * p.SquaredNorm() - (t*t) );}; - - inline S Sum() const { - return _v[0]+_v[1]+_v[2]+_v[3];} - - inline S Max() const { - return math::Max( math::Max( _v[0], _v[1] ), math::Max( _v[2], _v[3] )); } - - inline S Min() const { - return math::Min( math::Min( _v[0], _v[1] ), math::Min( _v[2], _v[3] )); } - - inline int MaxI() const { - int i= (_v[0] < _v[1]) ? 1:0; if (_v[i] < _v[2]) i=2; if (_v[i] < _v[3]) i=3; - return i;}; - - inline int MinI() const { - int i= (_v[0] > _v[1]) ? 1:0; if (_v[i] > _v[2]) i=2; if (_v[i] > _v[3]) i=3; - return i;}; - - inline PointType & Scale( const PointType & p ) { - _v[0] *= p._v[0]; _v[1] *= p._v[1]; _v[2] *= p._v[2]; _v[3] *= p._v[3]; return *this; } - - inline S StableDot ( const PointType & p ) const { - S k0=_v[0]*p._v[0], k1=_v[1]*p._v[1], k2=_v[2]*p._v[2], k3=_v[3]*p._v[3]; - int exp0,exp1,exp2,exp3; - frexp( double(k0), &exp0 );frexp( double(k1), &exp1 ); - frexp( double(k2), &exp2 );frexp( double(k3), &exp3 ); - if (exp0>exp1) { math::Swap(k0,k1); math::Swap(exp0,exp1); } - if (exp2>exp3) { math::Swap(k2,k3); math::Swap(exp2,exp3); } - if (exp0>exp2) { math::Swap(k0,k2); math::Swap(exp0,exp2); } - if (exp1>exp3) { math::Swap(k1,k3); math::Swap(exp1,exp3); } - if (exp2>exp3) { math::Swap(k2,k3); math::Swap(exp2,exp3); } - return ( (k0 + k1) + k2 ) +k3; } - - //@} +struct Point4:public Point<4,S>{ + typedef Point<4,S> Base; + inline Point4() : Base() {}; + inline Point4(const Point4& p):Base(p) {} + inline Point4(S a, S b, S c, S d):Base(a,b,c,d){}; + template + inline Point4(const Eigen::MatrixBase& other) : Base(other) {} }; +typedef Point<2,short> Point2s; +typedef Point<2,int> Point2i; +typedef Point<2,float> Point2f; +typedef Point<2,double> Point2d; +typedef Point<2,short> Vector2s; +typedef Point<2,int> Vector2i; +typedef Point<2,float> Vector2f; +typedef Point<2,double> Vector2d; -template -inline S Angle( Point3 const & p1, Point3 const & p2 ) -{ - S w = p1.Norm()*p2.Norm(); - if(w==0) return -1; - S t = (p1*p2)/w; - if(t>1) t = 1; - else if(t<-1) t = -1; - return (S) acos(t); -} - -// versione uguale alla precedente ma che assume che i due vettori siano unitari -template -inline S AngleN( Point3 const & p1, Point3 const & p2 ) -{ - S w = p1*p2; - if(w>1) - w = 1; - else if(w<-1) - w=-1; - return (S) acos(w); -} +typedef Point<3,short> Point3s; +typedef Point<3,int> Point3i; +typedef Point<3,float> Point3f; +typedef Point<3,double> Point3d; +typedef Point<3,short> Vector3s; +typedef Point<3,int> Vector3i; +typedef Point<3,float> Vector3f; +typedef Point<3,double> Vector3d; -template -inline S Norm( Point const & p ) -{ - return p.Norm(); -} - -template -inline S SquaredNorm( Point const & p ) -{ - return p.SquaredNorm(); -} - -template -inline Point & Normalize( Point & p ) -{ - p.Normalize(); - return p; -} - -template -inline S Distance( Point const & p1,Point const & p2 ) -{ - return (p1-p2).Norm(); -} - -template -inline S SquaredDistance( Point const & p1,Point const & p2 ) -{ - return (p1-p2).SquaredNorm(); -} - - -//template -//struct Point2:public Point<2,S>{ -// inline Point2(){}; -// inline Point2(Point<2,S> const & p):Point<2,S>(p){} ; -// inline Point2( const S a, const S b):Point<2,S>(a,b){}; -//}; -// -//template -//struct Point3:public Point3 { -// inline Point3(){}; -// inline Point3(Point3 const & p):Point3 (p){} -// inline Point3( const S a, const S b, const S c):Point3 (a,b,c){}; -//}; -// -// -//template -//struct Point4:public Point4{ -// inline Point4(){}; -// inline Point4(Point4 const & p):Point4(p){} -// inline Point4( const S a, const S b, const S c, const S d):Point4(a,b,c,d){}; -//}; - -typedef Point2 Point2s; -typedef Point2 Point2i; -typedef Point2 Point2f; -typedef Point2 Point2d; -typedef Point2 Vector2s; -typedef Point2 Vector2i; -typedef Point2 Vector2f; -typedef Point2 Vector2d; - -typedef Point3 Point3s; -typedef Point3 Point3i; -typedef Point3 Point3f; -typedef Point3 Point3d; -typedef Point3 Vector3s; -typedef Point3 Vector3i; -typedef Point3 Vector3f; -typedef Point3 Vector3d; - - -typedef Point4 Point4s; -typedef Point4 Point4i; -typedef Point4 Point4f; -typedef Point4 Point4d; -typedef Point4 Vector4s; -typedef Point4 Vector4i; -typedef Point4 Vector4f; -typedef Point4 Vector4d; +typedef Point<4,short> Point4s; +typedef Point<4,int> Point4i; +typedef Point<4,float> Point4f; +typedef Point<4,double> Point4d; +typedef Point<4,short> Vector4s; +typedef Point<4,int> Vector4i; +typedef Point<4,float> Vector4f; +typedef Point<4,double> Vector4d; /*@}*/ -//added only for backward compatibility -template -struct PointBase : Point -{ - PointBase() - :Point() - { - } -}; - } // end namespace ndim } // end namespace vcg #endif +#endif diff --git a/vcg/space/point2.h b/vcg/space/point2.h index 1fdfe20b..69be34db 100644 --- a/vcg/space/point2.h +++ b/vcg/space/point2.h @@ -76,11 +76,7 @@ public: inline Scalar &X() {return data()[0];} inline Scalar &Y() {return data()[1];} - inline Scalar & V( const int i ) - { - assert(i>=0 && i<2); - return data()[i]; - } + // overloaded to return a const reference inline const Scalar & V( const int i ) const { assert(i>=0 && i<2); @@ -98,45 +94,15 @@ public: inline Point2(const Eigen::MatrixBase& other) : Base(other) {} /// cross product + // hm.. this is not really a cross product inline Scalar operator ^ ( Point2 const & p ) const { return data()[0]*p.data()[1] - data()[1]*p.data()[0]; } - inline Point2 & Scale( const Scalar sx, const Scalar sy ) - { - data()[0] *= sx; - data()[1] *= sy; - return * this; - } - - /// lexical ordering - inline bool operator < ( Point2 const & p ) const - { - return (data()[1]!=p.data()[1])?(data()[1] ( Point2 const & p ) const - { - return (data()[1]!=p.data()[1])?(data()[1]>p.data()[1]): - (data()[0]>p.data()[0]); - } - /// lexical ordering - inline bool operator <= ( Point2 const & p ) const - { - return (data()[1]!=p.data()[1])?(data()[1]< p.data()[1]): - (data()[0]<=p.data()[0]); - } - /// lexical ordering - inline bool operator >= ( Point2 const & p ) const - { - return (data()[1]!=p.data()[1])?(data()[1]> p.data()[1]): - (data()[0]>=p.data()[0]); - } - /// returns the angle with X axis (radiants, in [-PI, +PI] ) - inline Scalar Angle() const { + inline Scalar Angle() const + { return math::Atan2(data()[1],data()[0]); } /// transform the point in cartesian coords into polar coords @@ -168,13 +134,6 @@ public: return *this; } - /// Questa funzione estende il vettore ad un qualsiasi numero di dimensioni - /// paddando gli elementi estesi con zeri - inline Scalar Ext( const int i ) const - { - if(i>=0 && i<2) return data()[i]; - else return 0; - } /// imports from 2D points of different types template inline void Import( const Point2 & b ) @@ -189,13 +148,6 @@ public: } }; // end class definition - -template -inline T Angle( Point2 const & p0, Point2 const & p1 ) -{ - return p1.Angle() - p0.Angle(); -} - typedef Point2 Point2s; typedef Point2 Point2i; typedef Point2 Point2f; diff --git a/vcg/space/point3.h b/vcg/space/point3.h index a1299fcd..adfce8ea 100644 --- a/vcg/space/point3.h +++ b/vcg/space/point3.h @@ -94,13 +94,6 @@ public: template inline Point3(const Eigen::MatrixBase& other) : Base(other) {} - /// Padding function: give a default 0 value to all the elements that are not in the [0..2] range. - /// Useful for managing in a consistent way object that could have point2 / point3 / point4 - inline Scalar Ext( const int i ) const - { - if(i>=0 && i<=2) return data()[i]; - else return 0; - } template inline void Import( const Eigen::MatrixBase& b ) @@ -141,11 +134,7 @@ public: inline Scalar &X() { return data()[0]; } inline Scalar &Y() { return data()[1]; } inline Scalar &Z() { return data()[2]; } - inline Scalar & V( const int i ) - { - assert(i>=0 && i<3); - return data()[i]; - } + // overloaded to return a const reference inline const Scalar & V( const int i ) const { assert(i>=0 && i<3); @@ -210,37 +199,6 @@ public: Box3<_Scalar> GetBBox(Box3<_Scalar> &bb) const; //@} -//@{ - - /** @name Comparison Operators. - Note that the reverse z prioritized ordering, useful in many situations. - **/ - - inline bool operator < ( Point3 const & p ) const - { - return (data()[2]!=p.data()[2])?(data()[2] ( Point3 const & p ) const - { - return (data()[2]!=p.data()[2])?(data()[2]>p.data()[2]): - (data()[1]!=p.data()[1])?(data()[1]>p.data()[1]): - (data()[0]>p.data()[0]); - } - inline bool operator <= ( Point3 const & p ) const - { - return (data()[2]!=p.data()[2])?(data()[2]< p.data()[2]): - (data()[1]!=p.data()[1])?(data()[1]< p.data()[1]): - (data()[0]<=p.data()[0]); - } - inline bool operator >= ( Point3 const & p ) const - { - return (data()[2]!=p.data()[2])?(data()[2]> p.data()[2]): - (data()[1]!=p.data()[1])?(data()[1]> p.data()[1]): - (data()[0]>=p.data()[0]); - } - //@} }; // end class definition diff --git a/vcg/space/point4.h b/vcg/space/point4.h index 5e8eda55..17a4038a 100644 --- a/vcg/space/point4.h +++ b/vcg/space/point4.h @@ -89,24 +89,13 @@ public: inline T &Z() {return Base::z();} inline T &W() {return Base::w();} - inline const T & V ( const int i ) const + // overloaded to return a const reference + inline const T & V (int i) const { assert(i>=0 && i<4); return data()[i]; } - inline T & V ( const int i ) - { - assert(i>=0 && i<4); - return data()[i]; - } - - /// Padding function: give a default 0 value to all the elements that are not in the [0..2] range. - /// Useful for managing in a consistent way object that could have point2 / point3 / point4 - inline T Ext( const int i ) const - { - if(i>=0 && i<=3) return data()[i]; - else return 0; - } + //@} inline Point4 VectProd ( const Point4 &x, const Point4 &z ) const @@ -125,45 +114,6 @@ public: return res; } - /// Homogeneous normalization (division by W) - inline Point4 & HomoNormalize() { - if (data()[3]!=0.0) { Base::template start<3>() /= coeff(3); coeffRef(3) = 1.0; } - return *this; - } - -//@{ - /** @name Comparison operators (lexicographical order) - **/ - inline bool operator < ( Point4 const & p ) const - { - return (data()[3]!=p.data()[3])?(data()[3] ( const Point4 & p ) const - { - return (data()[3]!=p.data()[3])?(data()[3]>p.data()[3]): - (data()[2]!=p.data()[2])?(data()[2]>p.data()[2]): - (data()[1]!=p.data()[1])?(data()[1]>p.data()[1]): - (data()[0]>p.data()[0]); - } - inline bool operator <= ( const Point4 & p ) const - { - return (data()[3]!=p.data()[3])?(data()[3]< p.data()[3]): - (data()[2]!=p.data()[2])?(data()[2]< p.data()[2]): - (data()[1]!=p.data()[1])?(data()[1]< p.data()[1]): - (data()[0]<=p.data()[0]); - } - inline bool operator >= ( const Point4 & p ) const - { - return (data()[3]!=p.data()[3])?(data()[3]> p.data()[3]): - (data()[2]!=p.data()[2])?(data()[2]> p.data()[2]): - (data()[1]!=p.data()[1])?(data()[1]> p.data()[1]): - (data()[0]>=p.data()[0]); - } -//@} - //@{ /** @name Dot products **/ @@ -205,7 +155,7 @@ double StableDot ( Point4 const & p0, Point4 const & p1 ) } typedef Point4 Point4s; -typedef Point4 Point4i; +typedef Point4 Point4i; typedef Point4 Point4f; typedef Point4 Point4d;