Port to eigen2: state of the mess:

* curently nothing change if you don't define VCG_USE_EIGEN
* make Matrix*, Point3 and Point4 derive Eigen::Matrix (still ugly)
* now catching all the dot products to replace them by .dot()
  note that most of meshlab already compile
This commit is contained in:
Paolo Cignoni 2008-10-27 19:35:17 +00:00
parent 69ebba04b9
commit ab200fc950
35 changed files with 1557 additions and 1205 deletions

View File

@ -91,7 +91,7 @@ void CreaseCut(MESH_TYPE &m, float angleRad)
if(!isBorderVertex) // for internal vertex we search the first crease and start from it if(!isBorderVertex) // for internal vertex we search the first crease and start from it
{ {
do { do {
ScalarType dotProd = iPos.FFlip()->cN() * iPos.f->N(); ScalarType dotProd = iPos.FFlip()->cN().dot(iPos.f->N());
iPos.NextFE(); iPos.NextFE();
if(dotProd<cosangle) break; if(dotProd<cosangle) break;
} while (startPos!=iPos); } while (startPos!=iPos);
@ -102,7 +102,7 @@ void CreaseCut(MESH_TYPE &m, float angleRad)
int curVertexCounter =vertInd; int curVertexCounter =vertInd;
do { // The real Loop do { // The real Loop
ScalarType dotProd=iPos.FFlip()->cN() * iPos.f->N(); // test normal with the next face (fflip) ScalarType dotProd=iPos.FFlip()->cN().dot(iPos.f->N()); // test normal with the next face (fflip)
size_t faceInd = Index(m,iPos.f); size_t faceInd = Index(m,iPos.f);
indVec[faceInd*3+ iPos.VInd()] = curVertexCounter; indVec[faceInd*3+ iPos.VInd()] = curVertexCounter;

View File

@ -147,7 +147,7 @@ template <class MESH> class BallPivoting: public AdvancingFront<MESH> {
if(d0 < min_edge || d0 > max_edge) continue; if(d0 < min_edge || d0 > max_edge) continue;
Point3x normal = (p1 - p0)^(p2 - p0); Point3x normal = (p1 - p0)^(p2 - p0);
if(normal * (p0 - baricenter) < 0) continue; if(normal.dot(p0 - baricenter) < 0) continue;
/* if(use_normals) { /* if(use_normals) {
if(normal * vv0->N() < 0) continue; if(normal * vv0->N() < 0) continue;
if(normal * vv1->N() < 0) continue; if(normal * vv1->N() < 0) continue;
@ -169,7 +169,7 @@ template <class MESH> class BallPivoting: public AdvancingFront<MESH> {
} }
//check on the other side there is not a surface //check on the other side there is not a surface
Point3x opposite = center + normal*(((center - p0)*normal)*2/normal.SquaredNorm()); Point3x opposite = center + normal*(((center - p0).dot(normal))*2/normal.SquaredNorm());
for(t = 0; t < n; t++) { for(t = 0; t < n; t++) {
VertexType &v = *(targets[t]); VertexType &v = *(targets[t]);
if((v.IsV()) && (opposite - v.P()).Norm() <= radius) if((v.IsV()) && (opposite - v.P()).Norm() <= radius)
@ -291,7 +291,7 @@ template <class MESH> class BallPivoting: public AdvancingFront<MESH> {
if(min_angle >= M_PI - 0.1) { if(min_angle >= M_PI - 0.1) {
return -1; return -1;
} }
if(candidate == NULL) { if(candidate == NULL) {
return -1; return -1;
} }
@ -304,7 +304,7 @@ template <class MESH> class BallPivoting: public AdvancingFront<MESH> {
assert(id != edge.v0 && id != edge.v1); assert(id != edge.v0 && id != edge.v1);
Point3x newnormal = ((candidate->P() - v0)^(v1 - v0)).Normalize(); Point3x newnormal = ((candidate->P() - v0)^(v1 - v0)).Normalize();
if(normal * newnormal < max_angle || this->nb[id] >= 2) { if(normal.dot(newnormal) < max_angle || this->nb[id] >= 2) {
return -1; return -1;
} }
@ -315,7 +315,7 @@ template <class MESH> class BallPivoting: public AdvancingFront<MESH> {
if((*k).v0 == id) touch = k; if((*k).v0 == id) touch = k;
//mark vertices close to candidate //mark vertices close to candidate
Mark(candidate); Mark(candidate);
return id; return id;
} }
@ -360,9 +360,9 @@ template <class MESH> class BallPivoting: public AdvancingFront<MESH> {
up /= uplen; up /= uplen;
ScalarType a11 = q1*q1; ScalarType a11 = q1.dot(q1);
ScalarType a12 = q1*q2; ScalarType a12 = q1.dot(q2);
ScalarType a22 = q2*q2; ScalarType a22 = q2.dot(q2);
ScalarType m = 4*(a11*a22 - a12*a12); ScalarType m = 4*(a11*a22 - a12*a12);
ScalarType l1 = 2*(a11*a22 - a22*a12)/m; ScalarType l1 = 2*(a11*a22 - a22*a12)/m;
@ -385,8 +385,8 @@ template <class MESH> class BallPivoting: public AdvancingFront<MESH> {
p.Normalize(); p.Normalize();
q.Normalize(); q.Normalize();
Point3x vec = p^q; Point3x vec = p^q;
ScalarType angle = acos(p*q); ScalarType angle = acos(p.dot(q));
if(vec*axis < 0) angle = -angle; if(vec.dot(axis) < 0) angle = -angle;
if(angle < 0) angle += 2*M_PI; if(angle < 0) angle += 2*M_PI;
return angle; return angle;
} }

View File

@ -334,7 +334,7 @@ static void Covariance(const MeshType & m, vcg::Point3<ScalarType> & bary, vcg::
// integral of (x,y,0) in the same triangle // integral of (x,y,0) in the same triangle
CoordType X(1/6.0,1/6.0,0); CoordType X(1/6.0,1/6.0,0);
vcg::Matrix33<ScalarType> A, // matrix that bring the vertices to (v1-v0,v2-v0,n) vcg::Matrix33<ScalarType> A, // matrix that bring the vertices to (v1-v0,v2-v0,n)
At,DC; DC;
for(fi = m.face.begin(); fi != m.face.end(); ++fi) for(fi = m.face.begin(); fi != m.face.end(); ++fi)
if(!(*fi).IsD()) if(!(*fi).IsD())
{ {
@ -350,18 +350,15 @@ static void Covariance(const MeshType & m, vcg::Point3<ScalarType> & bary, vcg::
A.SetColumn(2,n); A.SetColumn(2,n);
CoordType delta = P0 - bary; CoordType delta = P0 - bary;
At= A;
At.Transpose();
/* DC is calculated as integral of (A*x+delta) * (A*x+delta)^T over the triangle, /* DC is calculated as integral of (A*x+delta) * (A*x+delta)^T over the triangle,
where delta = v0-bary where delta = v0-bary
*/ */
DC.SetZero(); DC.SetZero();
DC+= A*C0*At; DC+= A*C0*A.transpose();
vcg::Matrix33<ScalarType> tmp; vcg::Matrix33<ScalarType> tmp;
tmp.OuterProduct(A*X,delta); tmp.OuterProduct(A*X,delta);
DC+= tmp; DC += tmp + tmp.transpose();
tmp.Transpose();
DC+= tmp; DC+= tmp;
tmp.OuterProduct(delta,delta); tmp.OuterProduct(delta,delta);
DC+=tmp*0.5; DC+=tmp*0.5;

View File

@ -488,7 +488,7 @@ static void VertexCoordLaplacianQuality(MeshType &m, int step, bool SmoothSelect
/* /*
Improved Laplacian Smoothing of Noisy Surface Meshes Improved Laplacian Smoothing of Noisy Surface Meshes
J. Vollmer, R. Mencl, and H. Müller J. Vollmer, R. Mencl, and H. M<EFBFBD>ller
EUROGRAPHICS Volume 18 (1999), Number 3 EUROGRAPHICS Volume 18 (1999), Number 3
*/ */
@ -1099,7 +1099,7 @@ static void FaceNormalAngleThreshold(MeshType &m,
{ {
if(! (*ep.f).IsV() ) if(! (*ep.f).IsV() )
{ {
ScalarType cosang=ep.f->N()*(*fi).N(); ScalarType cosang=ep.f->N().dot((*fi).N());
if(cosang >= sigma) if(cosang >= sigma)
{ {
ScalarType w = cosang-sigma; ScalarType w = cosang-sigma;
@ -1223,7 +1223,7 @@ static void FastFitMesh(MeshType &m,
for (;!ep.End();++ep) for (;!ep.End();++ep)
{ {
CoordType bc=Barycenter<FaceType>(*ep.F()); CoordType bc=Barycenter<FaceType>(*ep.F());
Sum += ep.F()->N()*(ep.F()->N()*(bc - (*vi).P())); Sum += ep.F()->N()*(ep.F()->N().dot(bc - (*vi).P()));
++cnt; ++cnt;
} }
TDV[*vi].np=(*vi).P()+ Sum*(1.0/cnt); TDV[*vi].np=(*vi).P()+ Sum*(1.0/cnt);

View File

@ -211,11 +211,8 @@ public:
tempMatrix.ExternalProduct(W,W); tempMatrix.ExternalProduct(W,W);
Q -= tempMatrix * 2.0f; Q -= tempMatrix * 2.0f;
Matrix33<ScalarType> Qt(Q);
Qt.Transpose();
// compute matrix Q^t M Q // compute matrix Q^t M Q
Matrix33<ScalarType> QtMQ = (Qt * M * Q); Matrix33<ScalarType> QtMQ = (Q.transpose() * M * Q);
CoordType bl = Q.GetColumn(0); CoordType bl = Q.GetColumn(0);
CoordType T1 = Q.GetColumn(1); CoordType T1 = Q.GetColumn(1);
@ -644,7 +641,7 @@ public:
int n_rot; int n_rot;
Jacobi(m33,lambda, vect,n_rot); Jacobi(m33,lambda, vect,n_rot);
vect.Transpose(); vect = vect.transpose().eval();
ScalarType normal = std::numeric_limits<ScalarType>::min(); ScalarType normal = std::numeric_limits<ScalarType>::min();
int normI = 0; int normI = 0;
for(int i = 0; i < 3; ++i) for(int i = 0; i < 3; ++i)

View File

@ -74,7 +74,7 @@ namespace tri {
f.Edge(2) = f.V(0)->P(); f.Edge(2) -= f.V(2)->P(); f.Edge(2) = f.V(0)->P(); f.Edge(2) -= f.V(2)->P();
// Calcolo di plane // Calcolo di plane
f.Plane().SetDirection(f.Edge(0)^f.Edge(1)); f.Plane().SetDirection(f.Edge(0)^f.Edge(1));
f.Plane().SetOffset(f.Plane().Direction() * f.V(0)->P()); f.Plane().SetOffset(f.Plane().Direction().dot(f.V(0)->P()));
f.Plane().Normalize(); f.Plane().Normalize();
// Calcolo migliore proiezione // Calcolo migliore proiezione
ScalarType nx = math::Abs(f.Plane().Direction()[0]); ScalarType nx = math::Abs(f.Plane().Direction()[0]);

View File

@ -721,12 +721,15 @@ namespace vcg{
delete []temp; delete []temp;
}; };
// for the transistion to eigen
Matrix transpose() Matrix transpose()
{ {
Matrix res = *this; Matrix res = *this;
res.Transpose(); res.Transpose();
return res; return res;
} }
// for the transistion to eigen
const Matrix& eval() { return *this; }
/*! /*!

View File

@ -403,6 +403,8 @@ public:
res.Transpose(); res.Transpose();
return res; return res;
} }
// for the transistion to eigen
const Matrix33& eval() { return *this; }
/// Funzione per costruire una matrice diagonale dati i tre elem. /// Funzione per costruire una matrice diagonale dati i tre elem.
Matrix33 & SetDiagonal(S *v) Matrix33 & SetDiagonal(S *v)

View File

@ -281,6 +281,16 @@ public:
return tmp; return tmp;
} }
// for the transistion to eigen
Matrix44 transpose() const
{
Matrix44 res = *this;
Transpose(res);
return res;
}
// for the transistion to eigen
const Matrix44& eval() { return *this; }
}; };
@ -289,7 +299,7 @@ public:
template <class T> class LinearSolve: public Matrix44<T> { template <class T> class LinearSolve: public Matrix44<T> {
public: public:
LinearSolve(const Matrix44<T> &m); LinearSolve(const Matrix44<T> &m);
Point4<T> Solve(const Point4<T> &b); // solve A · x = b Point4<T> Solve(const Point4<T> &b); // solve A <EFBFBD> x = b
///If you need to solve some equation you can use this function instead of Matrix44 one for speed. ///If you need to solve some equation you can use this function instead of Matrix44 one for speed.
T Determinant() const; T Determinant() const;
protected: protected:

View File

@ -26,8 +26,40 @@
#define EIGEN_MATRIXBASE_PLUGIN <vcg/math/eigen_vcgaddons.h> #define EIGEN_MATRIXBASE_PLUGIN <vcg/math/eigen_vcgaddons.h>
#include "../Eigen/LU"
#include "../Eigen/Geometry"
#include "../Eigen/Array" #include "../Eigen/Array"
#include "../Eigen/Core" #include "../Eigen/Core"
#include "base.h"
namespace Eigen {
template<> struct NumTraits<unsigned char>
{
typedef unsigned char Real;
typedef float FloatingPoint;
enum {
IsComplex = 0,
HasFloatingPoint = 0,
ReadCost = 1,
AddCost = 1,
MulCost = 1
};
};
template<> struct NumTraits<short int>
{
typedef short int Real;
typedef float FloatingPoint;
enum {
IsComplex = 0,
HasFloatingPoint = 0,
ReadCost = 1,
AddCost = 1,
MulCost = 1
};
};
}
#define VCG_EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, Op) \ #define VCG_EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Derived, Op) \
template<typename OtherDerived> \ template<typename OtherDerived> \
@ -54,4 +86,46 @@
VCG_EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, *=) \ VCG_EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, *=) \
VCG_EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, /=) VCG_EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, /=)
namespace vcg {
template<typename Derived1, typename Derived2>
typename Eigen::ei_traits<Derived1>::Scalar
Angle(const Eigen::MatrixBase<Derived1>& p1, const Eigen::MatrixBase<Derived2> & 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<Derived1>::Scalar Scalar;
Scalar w = p1.norm()*p2.norm();
if(w==0) return Scalar(-1);
Scalar t = (p1.dot(p2))/w;
if(t>1) t = 1;
else if(t<-1) t = -1;
return vcg::math::Acos(t);
}
template<typename Derived1>
inline typename Eigen::ei_traits<Derived1>::Scalar Norm( const Eigen::MatrixBase<Derived1>& p)
{ return p.norm(); }
template<typename Derived1>
inline typename Eigen::ei_traits<Derived1>::Scalar SquaredNorm( const Eigen::MatrixBase<Derived1>& p)
{ return p.norm2(); }
template<typename Derived1, typename Derived2>
inline typename Eigen::ei_traits<Derived1>::Scalar
Distance(const Eigen::MatrixBase<Derived1>& p1, const Eigen::MatrixBase<Derived2> & p2)
{ return (p1-p2).norm(); }
template<typename Derived1, typename Derived2>
inline typename Eigen::ei_traits<Derived1>::Scalar
SquaredDistance(const Eigen::MatrixBase<Derived1>& p1, const Eigen::MatrixBase<Derived2> & p2)
{ return (p1-p2).norm2(); }
}
#endif #endif

View File

@ -72,10 +72,15 @@ EIGEN_DEPRECATED inline unsigned int RowsNumber() const
* \param j the column index * \param j the column index
* \return the element * \return the element
*/ */
EIGEN_DEPRECATED inline Scalar ElementAt(unsigned int i, unsigned int j) EIGEN_DEPRECATED inline Scalar ElementAt(unsigned int i, unsigned int j) const
{ {
return (*this)(i,j); return (*this)(i,j);
}; }
EIGEN_DEPRECATED inline Scalar& ElementAt(unsigned int i, unsigned int j)
{
return (*this)(i,j);
}
/*! /*!
* \deprecated use *this.determinant() (or *this.lu().determinant() for large matrices) * \deprecated use *this.determinant() (or *this.lu().determinant() for large matrices)
@ -148,6 +153,8 @@ EIGEN_DEPRECATED void SwapRows(const unsigned int i, const unsigned int j)
row(i).swap(row(j)); row(i).swap(row(j));
}; };
Scalar* V() { return derived().data(); }
const Scalar* V() const { return derived().data(); }
/*! /*!
* \deprecated use *this.cwise() += k * \deprecated use *this.cwise() += k
@ -288,6 +295,8 @@ EIGEN_DEPRECATED void SetDiagonal(Scalar *v)
diagonal() = Map<Matrix<Scalar,RowsAtCompileTime,1> >(v,cols(),1); diagonal() = Map<Matrix<Scalar,RowsAtCompileTime,1> >(v,cols(),1);
} }
/** \deprecated use trace() */
EIGEN_DEPRECATED Scalar Trace() const { return trace(); }
/*! /*!
* \deprecated use *this = *this.transpose() * \deprecated use *this = *this.transpose()
@ -316,4 +325,13 @@ EIGEN_DEPRECATED void Dump()
printf("\n"); printf("\n");
} }
/** \deprecated use norm() */
EIGEN_DEPRECATED inline Scalar Norm() const { return norm(); }
/** \deprecated use squaredNorm() */
EIGEN_DEPRECATED inline Scalar SquaredNorm() const { return norm2(); }
/** \deprecated use normalize() or normalized() */
EIGEN_DEPRECATED inline Derived& Normalize() { normalize(); return derived(); }
/** \deprecated use .cross(p) */
inline EvalType operator ^ (const Derived& p ) const { return this->cross(p); }

View File

@ -73,7 +73,7 @@ static void UniformCone(int vn, std::vector<Point3<ScalarType > > &NN, ScalarTyp
ScalarType DotProd = cos(AngleRad); ScalarType DotProd = cos(AngleRad);
for(vi=NNT.begin();vi!=NNT.end();++vi) for(vi=NNT.begin();vi!=NNT.end();++vi)
{ {
if(dir*(*vi) >= DotProd) NN.push_back(*vi); if(dir.dot(*vi) >= DotProd) NN.push_back(*vi);
} }
} }
@ -124,7 +124,7 @@ static int BestMatchingNormal(const Point3x &n, std::vector<Point3x> &nv)
typename std::vector<Point3x>::iterator ni; typename std::vector<Point3x>::iterator ni;
for(ni=nv.begin();ni!=nv.end();++ni) for(ni=nv.begin();ni!=nv.end();++ni)
{ {
cosang=(*ni)*n; cosang=(*ni).dot(n);
if(cosang>bestang) { if(cosang>bestang) {
bestang=cosang; bestang=cosang;
ret=ni-nv.begin(); ret=ni-nv.begin();

View File

@ -23,8 +23,8 @@
#ifndef VCG_USE_EIGEN #ifndef VCG_USE_EIGEN
#include "deprecated_matrix.h" #include "deprecated_matrix.h"
#endif
#else
#ifndef MATRIX_VCGLIB #ifndef MATRIX_VCGLIB
#define MATRIX_VCGLIB #define MATRIX_VCGLIB
@ -69,10 +69,9 @@ public:
* @param Scalar (Templete Parameter) Specifies the ScalarType field. * @param Scalar (Templete Parameter) Specifies the ScalarType field.
*/ */
template<class _Scalar> template<class _Scalar>
class Matrix : public Eigen::Matrix<_Scalar,Eigen::Dynamic,Eigen::Dynamic> // FIXME col or row major ? class Matrix : public Eigen::Matrix<_Scalar,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> // FIXME col or row major ?
{ {
typedef Eigen::Matrix<_Scalar,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> _Base;
typedef Eigen::Matrix<_Scalar,Eigen::Dynamic,Eigen::Dynamic> _Base;
public: public:
@ -87,7 +86,7 @@ public:
* \param m the number of matrix rows * \param m the number of matrix rows
* \param n the number of matrix columns * \param n the number of matrix columns
*/ */
Matrix(unsigned int m, unsigned int n) Matrix(int m, int n)
: Base(m,n) : Base(m,n)
{ {
memset(Base::data(), 0, m*n*sizeof(Scalar)); memset(Base::data(), 0, m*n*sizeof(Scalar));
@ -100,10 +99,10 @@ public:
* \param n the number of matrix columns * \param n the number of matrix columns
* \param values the values of the matrix elements * \param values the values of the matrix elements
*/ */
Matrix(unsigned int m, unsigned int n, Scalar *values) Matrix(int m, int n, Scalar *values)
: Base(m.n) : Base(m,n)
{ {
*this = Eigen::Map<Eigen::Matrix<Scalar,Dynamic,Dynamic,RowMajor> >(values, m , n); *this = Eigen::Map<Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> >(values, m , n);
} }
/*! /*!
@ -197,3 +196,6 @@ void Invert(MatrixType & m)
} // end of namespace } // end of namespace
#endif #endif
#endif

View File

@ -21,14 +21,15 @@
* * * *
****************************************************************************/ ****************************************************************************/
// #ifndef VCG_USE_EIGEN #ifndef VCG_USE_EIGEN
#include "deprecated_matrix33.h" #include "deprecated_matrix33.h"
// #endif #else
#ifndef __VCGLIB_MATRIX33_H #ifndef __VCGLIB_MATRIX33_H
#define __VCGLIB_MATRIX33_H #define __VCGLIB_MATRIX33_H
#include "eigen.h" #include "eigen.h"
#include "matrix44.h"
namespace vcg{ namespace vcg{
template<class Scalar> class Matrix33; template<class Scalar> class Matrix33;
@ -48,17 +49,20 @@ namespace vcg {
@param S (Templete Parameter) Specifies the ScalarType field. @param S (Templete Parameter) Specifies the ScalarType field.
*/ */
template<class _Scalar> template<class _Scalar>
class Matrix33 : public Eigen::Matrix<_Scalar,3,3,RowMajor> // FIXME col or row major ? class Matrix33 : public Eigen::Matrix<_Scalar,3,3,Eigen::RowMajor> // FIXME col or row major ?
{ {
typedef Eigen::Matrix<_Scalar,Eigen::Dynamic,Eigen::Dynamic> _Base; typedef Eigen::Matrix<_Scalar,3,3,Eigen::RowMajor> _Base;
using _Base::coeff;
using _Base::coeffRef;
using _Base::setZero;
public: public:
_EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix,_Base); _EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix33,_Base);
typedef _Scalar ScalarType; typedef _Scalar ScalarType;
VCG_EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Matrix) VCG_EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Matrix33)
/// Default constructor /// Default constructor
inline Matrix33() : Base() {} inline Matrix33() : Base() {}
@ -67,10 +71,13 @@ public:
Matrix33(const Matrix33& m ) : Base(m) {} Matrix33(const Matrix33& m ) : Base(m) {}
/// create from a \b row-major array /// create from a \b row-major array
Matrix33(const Scalar * v ) : Base(Map<Matrix<Scalar,3,3,RowMajor>(v)) {} Matrix33(const Scalar * v ) : Base(Eigen::Map<Eigen::Matrix<Scalar,3,3,Eigen::RowMajor> >(v)) {}
/// create from Matrix44 excluding row and column k /// create from Matrix44 excluding row and column k
Matrix33(const Matrix44<S> & m, const int & k) : Base(m.minor(k,k)) {} Matrix33(const Matrix44<Scalar> & m, const int & k) : Base(m.minor(k,k)) {}
template<typename OtherDerived>
Matrix33(const Eigen::MatrixBase<OtherDerived>& other) : Base(other) {}
/*! /*!
* \deprecated use *this.row(i) * \deprecated use *this.row(i)
@ -86,13 +93,13 @@ public:
/** \deprecated */ /** \deprecated */
Matrix33 & SetRotateRad(S angle, const Point3<S> & axis ) Matrix33 & SetRotateRad(Scalar angle, const Point3<Scalar> & axis )
{ {
*this = Eigen::AngleAxis<Scalar>(angle,axis).toRotationMatrix(); *this = Eigen::AngleAxis<Scalar>(angle,axis).toRotationMatrix();
return (*this); return (*this);
} }
/** \deprecated */ /** \deprecated */
Matrix33 & SetRotateDeg(S angle, const Point3<S> & axis ){ Matrix33 & SetRotateDeg(Scalar angle, const Point3<Scalar> & axis ){
return SetRotateRad(math::ToRad(angle),axis); return SetRotateRad(math::ToRad(angle),axis);
} }
@ -100,7 +107,7 @@ public:
// Warning, this Inversion code can be HIGHLY NUMERICALLY UNSTABLE! // Warning, this Inversion code can be HIGHLY NUMERICALLY UNSTABLE!
// In most case you are advised to use the Invert() method based on SVD decomposition. // In most case you are advised to use the Invert() method based on SVD decomposition.
/** \deprecated */ /** \deprecated */
Matrix33 & FastInvert() { return *this = inverse(); } Matrix33 & FastInvert() { return *this = Base::inverse(); }
void show(FILE * fp) void show(FILE * fp)
{ {
@ -111,7 +118,7 @@ public:
/* /*
compute the matrix generated by the product of a * b^T compute the matrix generated by the product of a * b^T
*/ */
void ExternalProduct(const Point3<S> &a, const Point3<S> &b) void ExternalProduct(const Point3<Scalar> &a, const Point3<Scalar> &b)
{ {
for(int i=0;i<3;++i) for(int i=0;i<3;++i)
for(int j=0;j<3;++j) for(int j=0;j<3;++j)
@ -120,15 +127,15 @@ public:
/* Compute the Frobenius Norm of the Matrix /* Compute the Frobenius Norm of the Matrix
*/ */
ScalarType Norm() Scalar Norm() { return Base::cwise().abs2().sum(); }
{ // {
// FIXME looks like there is a bug: j is not used !!! // // FIXME looks like there is a bug: j is not used !!!
ScalarType SQsum=0; // Scalar SQsum=0;
for(int i=0;i<3;++i) // for(int i=0;i<3;++i)
for(int j=0;j<3;++j) // for(int j=0;j<3;++j)
SQsum += a[i]*a[i]; // SQsum += a[i]*a[i];
return (math::Sqrt(SQsum)); // return (math::Sqrt(SQsum));
} // }
/** /**
@ -136,7 +143,7 @@ public:
*/ */
// FIXME should be outside Matrix // FIXME should be outside Matrix
template <class STLPOINTCONTAINER > template <class STLPOINTCONTAINER >
void Covariance(const STLPOINTCONTAINER &points, Point3<S> &bp) { void Covariance(const STLPOINTCONTAINER &points, Point3<Scalar> &bp) {
assert(!points.empty()); assert(!points.empty());
typedef typename STLPOINTCONTAINER::const_iterator PointIte; typedef typename STLPOINTCONTAINER::const_iterator PointIte;
// first cycle: compute the barycenter // first cycle: compute the barycenter
@ -147,14 +154,12 @@ public:
this->setZero(); this->setZero();
vcg::Matrix33<ScalarType> A; vcg::Matrix33<ScalarType> A;
for( PointIte pi = points.begin(); pi != points.end(); ++pi) { for( PointIte pi = points.begin(); pi != points.end(); ++pi) {
Point3<S> p = (*pi)-bp; Point3<Scalar> p = (*pi)-bp;
A.OuterProduct(p,p); A.OuterProduct(p,p);
(*this)+= A; (*this)+= A;
} }
} }
/** /**
It computes the cross covariance matrix of two set of 3d points P and X; It computes the cross covariance matrix of two set of 3d points P and X;
it returns also the barycenters of P and X. it returns also the barycenters of P and X.
@ -168,14 +173,14 @@ public:
// FIXME should be outside Matrix // FIXME should be outside Matrix
template <class STLPOINTCONTAINER > template <class STLPOINTCONTAINER >
void CrossCovariance(const STLPOINTCONTAINER &P, const STLPOINTCONTAINER &X, void CrossCovariance(const STLPOINTCONTAINER &P, const STLPOINTCONTAINER &X,
Point3<S> &bp, Point3<S> &bx) Point3<Scalar> &bp, Point3<Scalar> &bx)
{ {
setZero(); setZero();
assert(P.size()==X.size()); assert(P.size()==X.size());
bx.setZero(); bx.setZero();
bp.setZero(); bp.setZero();
Matrix33<S> tmp; Matrix33<Scalar> tmp;
typename std::vector <Point3<S> >::const_iterator pi,xi; typename std::vector <Point3<Scalar> >::const_iterator pi,xi;
for(pi=P.begin(),xi=X.begin();pi!=P.end();++pi,++xi){ for(pi=P.begin(),xi=X.begin();pi!=P.end();++pi,++xi){
bp+=*pi; bp+=*pi;
bx+=*xi; bx+=*xi;
@ -193,15 +198,15 @@ public:
void WeightedCrossCovariance(const STLREALCONTAINER & weights, void WeightedCrossCovariance(const STLREALCONTAINER & weights,
const STLPOINTCONTAINER &P, const STLPOINTCONTAINER &P,
const STLPOINTCONTAINER &X, const STLPOINTCONTAINER &X,
Point3<S> &bp, Point3<Scalar> &bp,
Point3<S> &bx) Point3<Scalar> &bx)
{ {
SetZero(); setZero();
assert(P.size()==X.size()); assert(P.size()==X.size());
bx.SetZero(); bx.SetZero();
bp.SetZero(); bp.SetZero();
Matrix33<S> tmp; Matrix33<Scalar> tmp;
typename std::vector <Point3<S> >::const_iterator pi,xi; typename std::vector <Point3<Scalar> >::const_iterator pi,xi;
typename STLREALCONTAINER::const_iterator pw; typename STLREALCONTAINER::const_iterator pw;
for(pi=P.begin(),xi=X.begin();pi!=P.end();++pi,++xi){ for(pi=P.begin(),xi=X.begin();pi!=P.end();++pi,++xi){
@ -317,10 +322,12 @@ template <class S>
/// ///
typedef Matrix33<short> Matrix33s; typedef Matrix33<short> Matrix33s;
typedef Matrix33<int> Matrix33i; typedef Matrix33<int> Matrix33i;
typedef Matrix33<float> Matrix33f; typedef Matrix33<float> Matrix33f;
typedef Matrix33<double> Matrix33d; typedef Matrix33<double> Matrix33d;
} // end of namespace } // end of namespace
#endif #endif
#endif

View File

@ -8,7 +8,7 @@
* \ * * \ *
* All rights reserved. * * All rights reserved. *
* * * *
* This program is free software; you can redistribute it and/or modify * * 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 * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
@ -21,9 +21,9 @@
* * * *
****************************************************************************/ ****************************************************************************/
// #ifndef VCG_USE_EIGEN #ifndef VCG_USE_EIGEN
#include "deprecated_matrix44.h" #include "deprecated_matrix44.h"
// #endif #else
#ifndef __VCGLIB_MATRIX44 #ifndef __VCGLIB_MATRIX44
#define __VCGLIB_MATRIX44 #define __VCGLIB_MATRIX44
@ -83,17 +83,21 @@ for 'column' vectors.
/** This class represents a 4x4 matrix. T is the kind of element in the matrix. /** This class represents a 4x4 matrix. T is the kind of element in the matrix.
*/ */
template<typename _Scalar> template<typename _Scalar>
class Matrix44 : public Eigen::Matrix<_Scalar,4,4,RowMajor> // FIXME col or row major ! class Matrix44 : public Eigen::Matrix<_Scalar,4,4,Eigen::RowMajor> // FIXME col or row major !
{ {
typedef Eigen::Matrix<_Scalar,Eigen::Dynamic,Eigen::Dynamic> _Base; typedef Eigen::Matrix<_Scalar,4,4,Eigen::RowMajor> _Base;
using _Base::coeff;
using _Base::coeffRef;
using _Base::ElementAt;
using _Base::setZero;
public: public:
_EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix,_Base); _EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix44,_Base);
typedef _Scalar ScalarType; typedef _Scalar ScalarType;
VCG_EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Matrix) VCG_EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Matrix44)
/** \name Constructors /** \name Constructors
* No automatic casting and default constructor is empty * No automatic casting and default constructor is empty
@ -101,50 +105,51 @@ public:
Matrix44() : Base() {} Matrix44() : Base() {}
~Matrix44() {} ~Matrix44() {}
Matrix44(const Matrix44 &m) : Base(m) {} Matrix44(const Matrix44 &m) : Base(m) {}
Matrix33(const Scalar * v ) : Base(Map<Matrix<Scalar,4,4,RowMajor>(v)) {} Matrix44(const Scalar * v ) : Base(Eigen::Map<Eigen::Matrix<Scalar,4,4,Eigen::RowMajor> >(v)) {}
Scalar *V() { return Base::data(); } template<typename OtherDerived>
const Scalar *V() const { return Base::data(); } Matrix44(const Eigen::MatrixBase<OtherDerived>& other) : Base(other) {}
const typename Base::RowXpr operator[](int i) const { return Base::row(i); }
typename Base::RowXpr operator[](int i) { return Base::row(i); }
// return a copy of the i-th column // return a copy of the i-th column
typename Base::ColXpr GetColumn4(const int& i) const { return col(i); } typename Base::ColXpr GetColumn4(const int& i) const { return Base::col(i); }
Block<Matrix,3,1> GetColumn3(const int& i) const { return block<3,1>(0,i); } const Eigen::Block<Base,3,1> GetColumn3(const int& i) const { return this->template block<3,1>(0,i); }
typename Base::RowXpr GetRow4(const int& i) const { return col(i); } typename Base::RowXpr GetRow4(const int& i) const { return Base::row(i); }
Block<Matrix,1,3> GetRow3(const int& i) const { return block<1,3>(i,0); } Eigen::Block<Base,1,3> GetRow3(const int& i) const { return this->template block<1,3>(i,0); }
template <class Matrix44Type> template <class Matrix44Type>
void ToMatrix(Matrix44Type & m) const { m = (*this).cast<typename Matrix44Type::Scalar>(); } void ToMatrix(Matrix44Type & m) const { m = (*this).template cast<typename Matrix44Type::Scalar>(); }
void ToEulerAngles(Scalar &alpha, Scalar &beta, Scalar &gamma); void ToEulerAngles(Scalar &alpha, Scalar &beta, Scalar &gamma);
template <class Matrix44Type> template <class Matrix44Type>
void FromMatrix(const Matrix44Type & m) { for(int i = 0; i < 16; i++) data()[i] = m.data()[i]; } void FromMatrix(const Matrix44Type & m) { for(int i = 0; i < 16; i++) Base::data()[i] = m.data()[i]; }
void FromEulerAngles(T alpha, T beta, T gamma); void FromEulerAngles(Scalar alpha, Scalar beta, Scalar gamma);
void SetDiagonal(const T k); void SetDiagonal(const Scalar k);
Matrix44 &SetScale(const T sx, const T sy, const T sz); Matrix44 &SetScale(const Scalar sx, const Scalar sy, const Scalar sz);
Matrix44 &SetScale(const Point3<T> &t); Matrix44 &SetScale(const Point3<Scalar> &t);
Matrix44 &SetTranslate(const Point3<T> &t); Matrix44 &SetTranslate(const Point3<Scalar> &t);
Matrix44 &SetTranslate(const T sx, const T sy, const T sz); Matrix44 &SetTranslate(const Scalar sx, const Scalar sy, const Scalar sz);
Matrix44 &SetShearXY(const T sz); Matrix44 &SetShearXY(const Scalar sz);
Matrix44 &SetShearXZ(const T sy); Matrix44 &SetShearXZ(const Scalar sy);
Matrix44 &SetShearYZ(const T sx); Matrix44 &SetShearYZ(const Scalar sx);
///use radiants for angle. ///use radiants for angle.
Matrix44 &SetRotateDeg(T AngleDeg, const Point3<T> & axis); Matrix44 &SetRotateDeg(Scalar AngleDeg, const Point3<Scalar> & axis);
Matrix44 &SetRotateRad(T AngleRad, const Point3<T> & axis); Matrix44 &SetRotateRad(Scalar AngleRad, const Point3<Scalar> & axis);
T Determinant() const;
template <class Q> void Import(const Matrix44<Q> &m) { template <class Q> void Import(const Matrix44<Q> &m) {
for(int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
_a[i] = (T)(m.V()[i]); Base::data()[i] = (Scalar)(m.data()[i]);
} }
template <class Q> template <class Q>
static inline Matrix44 Construct( const Matrix44<Q> & b ) static inline Matrix44 Construct( const Matrix44<Q> & b )
{ {
Matrix44<T> tmp; tmp.FromMatrix(b); Matrix44 tmp; tmp.FromMatrix(b);
return tmp; return tmp;
} }
@ -173,7 +178,6 @@ protected:
///Premultiply ///Premultiply
template <class T> Point3<T> operator*(const Matrix44<T> &m, const Point3<T> &p); template <class T> Point3<T> operator*(const Matrix44<T> &m, const Point3<T> &p);
template <class T> Matrix44<T> &Transpose(Matrix44<T> &m);
//return NULL matrix if not invertible //return NULL matrix if not invertible
template <class T> Matrix44<T> &Invert(Matrix44<T> &m); template <class T> Matrix44<T> &Invert(Matrix44<T> &m);
template <class T> Matrix44<T> Inverse(const Matrix44<T> &m); template <class T> Matrix44<T> Inverse(const Matrix44<T> &m);
@ -184,27 +188,6 @@ typedef Matrix44<float> Matrix44f;
typedef Matrix44<double> Matrix44d; typedef Matrix44<double> Matrix44d;
template <class T> Matrix44<T>::Matrix44(const Matrix44<T> &m) {
memcpy((T *)_a, (T *)m._a, 16 * sizeof(T));
}
template <class T> Matrix44<T>::Matrix44(const T v[]) {
memcpy((T *)_a, v, 16 * sizeof(T));
}
template <class T> T &Matrix44<T>::ElementAt(const int row, const int col) {
assert(row >= 0 && row < 4);
assert(col >= 0 && col < 4);
return _a[(row<<2) + col];
}
template <class T> T Matrix44<T>::ElementAt(const int row, const int col) const {
assert(row >= 0 && row < 4);
assert(col >= 0 && col < 4);
return _a[(row<<2) + col];
}
//template <class T> T &Matrix44<T>::operator[](const int i) { //template <class T> T &Matrix44<T>::operator[](const int i) {
// assert(i >= 0 && i < 16); // assert(i >= 0 && i < 16);
// return ((T *)_a)[i]; // return ((T *)_a)[i];
@ -214,116 +197,7 @@ template <class T> T Matrix44<T>::ElementAt(const int row, const int col) const
// assert(i >= 0 && i < 16); // assert(i >= 0 && i < 16);
// return ((T *)_a)[i]; // return ((T *)_a)[i];
//} //}
template <class T> T *Matrix44<T>::operator[](const int i) {
assert(i >= 0 && i < 4);
return _a+i*4;
}
template <class T> const T *Matrix44<T>::operator[](const int i) const {
assert(i >= 0 && i < 4);
return _a+i*4;
}
template <class T> T *Matrix44<T>::V() { return _a;}
template <class T> const T *Matrix44<T>::V() const { return _a;}
template <class T> Matrix44<T> Matrix44<T>::operator+(const Matrix44 &m) const {
Matrix44<T> ret;
for(int i = 0; i < 16; i++)
ret.V()[i] = V()[i] + m.V()[i];
return ret;
}
template <class T> Matrix44<T> Matrix44<T>::operator-(const Matrix44 &m) const {
Matrix44<T> ret;
for(int i = 0; i < 16; i++)
ret.V()[i] = V()[i] - m.V()[i];
return ret;
}
template <class T> Matrix44<T> Matrix44<T>::operator*(const Matrix44 &m) const {
Matrix44 ret;
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++) {
T t = 0.0;
for(int k = 0; k < 4; k++)
t += ElementAt(i, k) * m.ElementAt(k, j);
ret.ElementAt(i, j) = t;
}
return ret;
}
template <class T> Matrix44<T> Matrix44<T>::operator*(const Matrix44Diag<T> &m) const {
Matrix44 ret = (*this);
for(int i = 0; i < 4; ++i)
for(int j = 0; j < 4; ++j)
ret[i][j]*=m[i];
return ret;
}
template <class T> Point4<T> Matrix44<T>::operator*(const Point4<T> &v) const {
Point4<T> ret;
for(int i = 0; i < 4; i++){
T t = 0.0;
for(int k = 0; k < 4; k++)
t += ElementAt(i,k) * v[k];
ret[i] = t;
}
return ret;
}
template <class T> bool Matrix44<T>::operator==(const Matrix44 &m) const {
for(int i = 0; i < 4; ++i)
for(int j = 0; j < 4; ++j)
if(ElementAt(i,j) != m.ElementAt(i,j))
return false;
return true;
}
template <class T> bool Matrix44<T>::operator!=(const Matrix44 &m) const {
for(int i = 0; i < 4; ++i)
for(int j = 0; j < 4; ++j)
if(ElementAt(i,j) != m.ElementAt(i,j))
return true;
return false;
}
template <class T> Matrix44<T> Matrix44<T>::operator-() const {
Matrix44<T> res;
for(int i = 0; i < 16; i++)
res.V()[i] = -V()[i];
return res;
}
template <class T> Matrix44<T> Matrix44<T>::operator*(const T k) const {
Matrix44<T> res;
for(int i = 0; i < 16; i++)
res.V()[i] =V()[i] * k;
return res;
}
template <class T> void Matrix44<T>::operator+=(const Matrix44 &m) {
for(int i = 0; i < 16; i++)
V()[i] += m.V()[i];
}
template <class T> void Matrix44<T>::operator-=(const Matrix44 &m) {
for(int i = 0; i < 16; i++)
V()[i] -= m.V()[i];
}
template <class T> void Matrix44<T>::operator*=( const Matrix44 & m ) {
*this = *this *m;
/*for(int i = 0; i < 4; i++) { //sbagliato
Point4<T> t(0, 0, 0, 0);
for(int k = 0; k < 4; k++) {
for(int j = 0; j < 4; j++) {
t[k] += ElementAt(i, k) * m.ElementAt(k, j);
}
}
for(int l = 0; l < 4; l++)
ElementAt(i, l) = t[l];
} */
}
template < class PointType , class T > void operator*=( std::vector<PointType> &vert, const Matrix44<T> & m ) { template < class PointType , class T > void operator*=( std::vector<PointType> &vert, const Matrix44<T> & m ) {
typename std::vector<PointType>::iterator ii; typename std::vector<PointType>::iterator ii;
@ -331,21 +205,16 @@ template < class PointType , class T > void operator*=( std::vector<PointType> &
(*ii).P()=m * (*ii).P(); (*ii).P()=m * (*ii).P();
} }
template <class T> void Matrix44<T>::operator*=( const T k ) {
for(int i = 0; i < 16; i++)
_a[i] *= k;
}
template <class T> template <class T>
void Matrix44<T>::ToEulerAngles(T &alpha, T &beta, T &gamma) void Matrix44<T>::ToEulerAngles(Scalar &alpha, Scalar &beta, Scalar &gamma)
{ {
alpha = atan2(ElementAt(1,2), ElementAt(2,2)); alpha = atan2(coeff(1,2), coeff(2,2));
beta = asin(-ElementAt(0,2)); beta = asin(-coeff(0,2));
gamma = atan2(ElementAt(0,1), ElementAt(1,1)); gamma = atan2(coeff(0,1), coeff(1,1));
} }
template <class T> template <class T>
void Matrix44<T>::FromEulerAngles(T alpha, T beta, T gamma) void Matrix44<T>::FromEulerAngles(Scalar alpha, Scalar beta, Scalar gamma)
{ {
this->SetZero(); this->SetZero();
@ -371,28 +240,20 @@ void Matrix44<T>::FromEulerAngles(T alpha, T beta, T gamma)
ElementAt(3,3) = 1; ElementAt(3,3) = 1;
} }
template <class T> void Matrix44<T>::SetZero() { template <class T> void Matrix44<T>::SetDiagonal(const Scalar k) {
memset((T *)_a, 0, 16 * sizeof(T)); setZero();
}
template <class T> void Matrix44<T>::SetIdentity() {
SetDiagonal(1);
}
template <class T> void Matrix44<T>::SetDiagonal(const T k) {
SetZero();
ElementAt(0, 0) = k; ElementAt(0, 0) = k;
ElementAt(1, 1) = k; ElementAt(1, 1) = k;
ElementAt(2, 2) = k; ElementAt(2, 2) = k;
ElementAt(3, 3) = 1; ElementAt(3, 3) = 1;
} }
template <class T> Matrix44<T> &Matrix44<T>::SetScale(const Point3<T> &t) { template <class T> Matrix44<T> &Matrix44<T>::SetScale(const Point3<Scalar> &t) {
SetScale(t[0], t[1], t[2]); SetScale(t[0], t[1], t[2]);
return *this; return *this;
} }
template <class T> Matrix44<T> &Matrix44<T>::SetScale(const T sx, const T sy, const T sz) { template <class T> Matrix44<T> &Matrix44<T>::SetScale(const Scalar sx, const Scalar sy, const Scalar sz) {
SetZero(); setZero();
ElementAt(0, 0) = sx; ElementAt(0, 0) = sx;
ElementAt(1, 1) = sy; ElementAt(1, 1) = sy;
ElementAt(2, 2) = sz; ElementAt(2, 2) = sz;
@ -400,23 +261,23 @@ template <class T> Matrix44<T> &Matrix44<T>::SetScale(const T sx, const T sy, co
return *this; return *this;
} }
template <class T> Matrix44<T> &Matrix44<T>::SetTranslate(const Point3<T> &t) { template <class T> Matrix44<T> &Matrix44<T>::SetTranslate(const Point3<Scalar> &t) {
SetTranslate(t[0], t[1], t[2]); SetTranslate(t[0], t[1], t[2]);
return *this; return *this;
} }
template <class T> Matrix44<T> &Matrix44<T>::SetTranslate(const T tx, const T ty, const T tz) { template <class T> Matrix44<T> &Matrix44<T>::SetTranslate(const Scalar tx, const Scalar ty, const Scalar tz) {
SetIdentity(); Base::setIdentity();
ElementAt(0, 3) = tx; ElementAt(0, 3) = tx;
ElementAt(1, 3) = ty; ElementAt(1, 3) = ty;
ElementAt(2, 3) = tz; ElementAt(2, 3) = tz;
return *this; return *this;
} }
template <class T> Matrix44<T> &Matrix44<T>::SetRotateDeg(T AngleDeg, const Point3<T> & axis) { template <class T> Matrix44<T> &Matrix44<T>::SetRotateDeg(Scalar AngleDeg, const Point3<Scalar> & axis) {
return SetRotateRad(math::ToRad(AngleDeg),axis); return SetRotateRad(math::ToRad(AngleDeg),axis);
} }
template <class T> Matrix44<T> &Matrix44<T>::SetRotateRad(T AngleRad, const Point3<T> & axis) { template <class T> Matrix44<T> &Matrix44<T>::SetRotateRad(Scalar AngleRad, const Point3<Scalar> & axis) {
//angle = angle*(T)3.14159265358979323846/180; e' in radianti! //angle = angle*(T)3.14159265358979323846/180; e' in radianti!
T c = math::Cos(AngleRad); T c = math::Cos(AngleRad);
T s = math::Sin(AngleRad); T s = math::Sin(AngleRad);
@ -436,9 +297,9 @@ template <class T> Matrix44<T> &Matrix44<T>::SetRotateRad(T AngleRad, const Poin
ElementAt(2,2) = t[2]*t[2]*q +c; ElementAt(2,2) = t[2]*t[2]*q +c;
ElementAt(2,3) = 0; ElementAt(2,3) = 0;
ElementAt(3,0) = 0; ElementAt(3,0) = 0;
ElementAt(3,1) = 0; ElementAt(3,1) = 0;
ElementAt(3,2) = 0; ElementAt(3,2) = 0;
ElementAt(3,3) = 1; ElementAt(3,3) = 1;
return *this; return *this;
} }
@ -461,20 +322,20 @@ template <class T> Matrix44<T> &Matrix44<T>::SetRotateRad(T AngleRad, const Poin
*/ */
template <class T> Matrix44<T> & Matrix44<T>:: SetShearXY( const T sh) {// shear the X coordinate as the Y coordinate change template <class T> Matrix44<T> & Matrix44<T>::SetShearXY( const Scalar sh) {// shear the X coordinate as the Y coordinate change
SetIdentity(); Base::setIdentity();
ElementAt(0,1) = sh; ElementAt(0,1) = sh;
return *this; return *this;
} }
template <class T> Matrix44<T> & Matrix44<T>:: SetShearXZ( const T sh) {// shear the X coordinate as the Z coordinate change template <class T> Matrix44<T> & Matrix44<T>::SetShearXZ( const Scalar sh) {// shear the X coordinate as the Z coordinate change
SetIdentity(); Base::setIdentity();
ElementAt(0,2) = sh; ElementAt(0,2) = sh;
return *this; return *this;
} }
template <class T> Matrix44<T> &Matrix44<T>:: SetShearYZ( const T sh) {// shear the Y coordinate as the Z coordinate change template <class T> Matrix44<T> &Matrix44<T>::SetShearYZ( const Scalar sh) {// shear the Y coordinate as the Z coordinate change
SetIdentity(); Base::setIdentity();
ElementAt(1,2) = sh; ElementAt(1,2) = sh;
return *this; return *this;
} }
@ -546,28 +407,28 @@ bool Decompose(Matrix44<T> &M, Point3<T> &ScaleV, Point3<T> &ShearV, Point3<T> &
R[0]=M.GetColumn3(0); R[0]=M.GetColumn3(0);
R[0].Normalize(); R[0].Normalize();
ShearV[0]=R[0]*M.GetColumn3(1); // xy shearing ShearV[0]=R[0].dot(M.GetColumn3(1)); // xy shearing
R[1]= M.GetColumn3(1)-R[0]*ShearV[0]; R[1]= M.GetColumn3(1)-R[0]*ShearV[0];
assert(math::Abs(R[1]*R[0])<1e-10); assert(math::Abs(R[1].dot(R[0]))<1e-10);
ScaleV[1]=Norm(R[1]); // y scaling ScaleV[1]=Norm(R[1]); // y scaling
R[1]=R[1]/ScaleV[1]; R[1]=R[1]/ScaleV[1];
ShearV[0]=ShearV[0]/ScaleV[1]; ShearV[0]=ShearV[0]/ScaleV[1];
ShearV[1]=R[0]*M.GetColumn3(2); // xz shearing ShearV[1]=R[0].dot(M.GetColumn3(2)); // xz shearing
R[2]= M.GetColumn3(2)-R[0]*ShearV[1]; R[2]= M.GetColumn3(2)-R[0]*ShearV[1];
assert(math::Abs(R[2]*R[0])<1e-10); assert(math::Abs(R[2].dot(R[0]))<1e-10);
R[2] = R[2]-R[1]*(R[2]*R[1]); R[2] = R[2]-R[1]*(R[2].dot(R[1]));
assert(math::Abs(R[2]*R[1])<1e-10); assert(math::Abs(R[2].dot(R[1]))<1e-10);
assert(math::Abs(R[2]*R[0])<1e-10); assert(math::Abs(R[2].dot(R[0]))<1e-10);
ScaleV[2]=Norm(R[2]); ScaleV[2]=Norm(R[2]);
ShearV[1]=ShearV[1]/ScaleV[2]; ShearV[1]=ShearV[1]/ScaleV[2];
R[2]=R[2]/ScaleV[2]; R[2]=R[2]/ScaleV[2];
assert(math::Abs(R[2]*R[1])<1e-10); assert(math::Abs(R[2].dot(R[1]))<1e-10);
assert(math::Abs(R[2]*R[0])<1e-10); assert(math::Abs(R[2].dot(R[0]))<1e-10);
ShearV[2]=R[1]*M.GetColumn3(2); // yz shearing ShearV[2]=R[1].dot(M.GetColumn3(2)); // yz shearing
ShearV[2]=ShearV[2]/ScaleV[2]; ShearV[2]=ShearV[2]/ScaleV[2];
int i,j; int i,j;
for(i=0;i<3;++i) for(i=0;i<3;++i)
@ -608,15 +469,6 @@ bool Decompose(Matrix44<T> &M, Point3<T> &ScaleV, Point3<T> &ShearV, Point3<T> &
return true; return true;
} }
template <class T> T Matrix44<T>::Determinant() const {
LinearSolve<T> solve(*this);
return solve.Determinant();
}
template <class T> Point3<T> operator*(const Matrix44<T> &m, const Point3<T> &p) { template <class T> Point3<T> operator*(const Matrix44<T> &m, const Point3<T> &p) {
T w; T w;
Point3<T> s; Point3<T> s;
@ -628,24 +480,19 @@ template <class T> Point3<T> operator*(const Matrix44<T> &m, const Point3<T> &p)
return s; return s;
} }
//template <class T> Point3<T> operator*(const Point3<T> &p, const Matrix44<T> &m) {
// template <class T> Point3<T> operator*(const Point3<T> &p, const Matrix44<T> &m) {
// T w; // T w;
// Point3<T> s; // Point3<T> s;
// s[0] = m.ElementAt(0, 0)*p[0] + m.ElementAt(1, 0)*p[1] + m.ElementAt(2, 0)*p[2] + m.ElementAt(3, 0); // s[0] = m.ElementAt(0, 0)*p[0] + m.ElementAt(1, 0)*p[1] + m.ElementAt(2, 0)*p[2] + m.ElementAt(3, 0);
// s[1] = m.ElementAt(0, 1)*p[0] + m.ElementAt(1, 1)*p[1] + m.ElementAt(2, 1)*p[2] + m.ElementAt(3, 1); // s[1] = m.ElementAt(0, 1)*p[0] + m.ElementAt(1, 1)*p[1] + m.ElementAt(2, 1)*p[2] + m.ElementAt(3, 1);
// s[2] = m.ElementAt(0, 2)*p[0] + m.ElementAt(1, 2)*p[1] + m.ElementAt(2, 2)*p[2] + m.ElementAt(3, 2); // s[2] = m.ElementAt(0, 2)*p[0] + m.ElementAt(1, 2)*p[1] + m.ElementAt(2, 2)*p[2] + m.ElementAt(3, 2);
// w = m.ElementAt(0, 3)*p[0] + m.ElementAt(1, 3)*p[1] + m.ElementAt(2, 3)*p[2] + m.ElementAt(3, 3); // w = m.ElementAt(0, 3)*p[0] + m.ElementAt(1, 3)*p[1] + m.ElementAt(2, 3)*p[2] + m.ElementAt(3, 3);
// if(w != 0) s /= w; // if(w != 0) s /= w;
// return s; // return s;
//} // }
template <class T> Matrix44<T> &Transpose(Matrix44<T> &m) {
for(int i = 1; i < 4; i++)
for(int j = 0; j < i; j++) {
math::Swap(m.ElementAt(i, j), m.ElementAt(j, i));
}
return m;
}
/* /*
To invert a matrix you can To invert a matrix you can
@ -658,194 +505,16 @@ template <class T> Matrix44<T> &Transpose(Matrix44<T> &m) {
invertedMatrix = vcg::Inverse(untouchedMatrix); invertedMatrix = vcg::Inverse(untouchedMatrix);
*/ */
template <class T> Matrix44<T> & Invert(Matrix44<T> &m) { template <class T> Matrix44<T> & Invert(Matrix44<T> &m) {
LinearSolve<T> solve(m); return m = m.lu().inverse();
for(int j = 0; j < 4; j++) { //Find inverse by columns.
Point4<T> col(0, 0, 0, 0);
col[j] = 1.0;
col = solve.Solve(col);
for(int i = 0; i < 4; i++)
m.ElementAt(i, j) = col[i];
}
return m;
} }
template <class T> Matrix44<T> Inverse(const Matrix44<T> &m) { template <class T> Matrix44<T> Inverse(const Matrix44<T> &m) {
LinearSolve<T> solve(m); return m.lu().inverse();
Matrix44<T> res;
for(int j = 0; j < 4; j++) { //Find inverse by columns.
Point4<T> col(0, 0, 0, 0);
col[j] = 1.0;
col = solve.Solve(col);
for(int i = 0; i < 4; i++)
res.ElementAt(i, j) = col[i];
}
return res;
} }
/* LINEAR SOLVE IMPLEMENTATION */
template <class T> LinearSolve<T>::LinearSolve(const Matrix44<T> &m): Matrix44<T>(m) {
if(!Decompose()) {
for(int i = 0; i < 4; i++)
index[i] = i;
Matrix44<T>::SetZero();
}
}
template <class T> T LinearSolve<T>::Determinant() const {
T det = d;
for(int j = 0; j < 4; j++)
det *= this-> ElementAt(j, j);
return det;
}
/*replaces a matrix by its LU decomposition of a rowwise permutation.
d is +or -1 depeneing of row permutation even or odd.*/
#define TINY 1e-100
template <class T> bool LinearSolve<T>::Decompose() {
/* Matrix44<T> A;
for(int i = 0; i < 16; i++)
A[i] = operator[](i);
SetIdentity();
Point4<T> scale;
// Set scale factor, scale(i) = max( |a(i,j)| ), for each row
for(int i = 0; i < 4; i++ ) {
index[i] = i; // Initialize row index list
T scalemax = (T)0.0;
for(int j = 0; j < 4; j++)
scalemax = (scalemax > math::Abs(A.ElementAt(i,j))) ? scalemax : math::Abs(A.ElementAt(i,j));
scale[i] = scalemax;
}
// Loop over rows k = 1, ..., (N-1)
int signDet = 1;
for(int k = 0; k < 3; k++ ) {
// Select pivot row from max( |a(j,k)/s(j)| )
T ratiomax = (T)0.0;
int jPivot = k;
for(int i = k; i < 4; i++ ) {
T ratio = math::Abs(A.ElementAt(index[i], k))/scale[index[i]];
if(ratio > ratiomax) {
jPivot = i;
ratiomax = ratio;
}
}
// Perform pivoting using row index list
int indexJ = index[k];
if( jPivot != k ) { // Pivot
indexJ = index[jPivot];
index[jPivot] = index[k]; // Swap index jPivot and k
index[k] = indexJ;
signDet *= -1; // Flip sign of determinant
}
// Perform forward elimination
for(int i=k+1; i < 4; i++ ) {
T coeff = A.ElementAt(index[i],k)/A.ElementAt(indexJ,k);
for(int j=k+1; j < 4; j++ )
A.ElementAt(index[i],j) -= coeff*A.ElementAt(indexJ,j);
A.ElementAt(index[i],k) = coeff;
//for( j=1; j< 4; j++ )
// ElementAt(index[i],j) -= A.ElementAt(index[i], k)*ElementAt(indexJ, j);
}
}
for(int i = 0; i < 16; i++)
operator[](i) = A[i];
d = signDet;
// this = A;
return true; */
d = 1; //no permutation still
T scaling[4];
int i,j,k;
//Saving the scvaling information per row
for(i = 0; i < 4; i++) {
T largest = 0.0;
for(j = 0; j < 4; j++) {
T t = math::Abs(this->ElementAt(i, j));
if (t > largest) largest = t;
}
if (largest == 0.0) { //oooppps there is a zero row!
return false;
}
scaling[i] = (T)1.0 / largest;
}
int imax = 0;
for(j = 0; j < 4; j++) {
for(i = 0; i < j; i++) {
T sum = this->ElementAt(i,j);
for(int k = 0; k < i; k++)
sum -= this->ElementAt(i,k)*this->ElementAt(k,j);
this->ElementAt(i,j) = sum;
}
T largest = 0.0;
for(i = j; i < 4; i++) {
T sum = this->ElementAt(i,j);
for(k = 0; k < j; k++)
sum -= this->ElementAt(i,k)*this->ElementAt(k,j);
this->ElementAt(i,j) = sum;
T t = scaling[i] * math::Abs(sum);
if(t >= largest) {
largest = t;
imax = i;
}
}
if (j != imax) {
for (int k = 0; k < 4; k++) {
T dum = this->ElementAt(imax,k);
this->ElementAt(imax,k) = this->ElementAt(j,k);
this->ElementAt(j,k) = dum;
}
d = -(d);
scaling[imax] = scaling[j];
}
index[j]=imax;
if (this->ElementAt(j,j) == 0.0) this->ElementAt(j,j) = (T)TINY;
if (j != 3) {
T dum = (T)1.0 / (this->ElementAt(j,j));
for (i = j+1; i < 4; i++)
this->ElementAt(i,j) *= dum;
}
}
return true;
}
template <class T> Point4<T> LinearSolve<T>::Solve(const Point4<T> &b) {
Point4<T> x(b);
int first = -1, ip;
for(int i = 0; i < 4; i++) {
ip = index[i];
T sum = x[ip];
x[ip] = x[i];
if(first!= -1)
for(int j = first; j <= i-1; j++)
sum -= this->ElementAt(i,j) * x[j];
else
if(sum) first = i;
x[i] = sum;
}
for (int i = 3; i >= 0; i--) {
T sum = x[i];
for (int j = i+1; j < 4; j++)
sum -= this->ElementAt(i, j) * x[j];
x[i] = sum / this->ElementAt(i, i);
}
return x;
}
} //namespace } //namespace
#endif #endif
#endif

View File

@ -137,16 +137,12 @@ bool ComputeWeightedRigidMatchMatrix(Matrix44x &res,
) )
{ {
Matrix33x tmp;
Matrix33x ccm; Matrix33x ccm;
Point3x bfix,bmov; // baricenter of src e trg Point3x bfix,bmov; // baricenter of src e trg
ccm.WeightedCrossCovariance(weights,Pmov,Pfix,bmov,bfix); ccm.WeightedCrossCovariance(weights,Pmov,Pfix,bmov,bfix);
Matrix33x cyc; // the cyclic components of the cross covariance matrix. Matrix33x cyc; // the cyclic components of the cross covariance matrix.
cyc=ccm; cyc=ccm - ccm.transpose();
tmp=ccm;
tmp.Transpose();
cyc-=tmp;
Matrix44x QQ; Matrix44x QQ;
QQ.SetZero(); QQ.SetZero();
@ -157,9 +153,7 @@ bool ComputeWeightedRigidMatchMatrix(Matrix44x &res,
RM[0][0]=-ccm.Trace(); RM[0][0]=-ccm.Trace();
RM[1][1]=-ccm.Trace(); RM[1][1]=-ccm.Trace();
RM[2][2]=-ccm.Trace(); RM[2][2]=-ccm.Trace();
RM+=ccm; RM += ccm + ccm.transpose();
ccm.Transpose();
RM+=ccm;
QQ[0][0] = ccm.Trace(); QQ[0][0] = ccm.Trace();
QQ[0][1] = D[0]; QQ[0][2] = D[1]; QQ[0][3] = D[2]; QQ[0][1] = D[0]; QQ[0][2] = D[1]; QQ[0][3] = D[2];
@ -208,16 +202,12 @@ bool ComputeRigidMatchMatrix(Matrix44x &res,
Point3x &tr) Point3x &tr)
{ {
Matrix33x tmp;
Matrix33x ccm; Matrix33x ccm;
Point3x bfix,bmov; // baricenter of src e trg Point3x bfix,bmov; // baricenter of src e trg
ccm.CrossCovariance(Pmov,Pfix,bmov,bfix); ccm.CrossCovariance(Pmov,Pfix,bmov,bfix);
Matrix33x cyc; // the cyclic components of the cross covariance matrix. Matrix33x cyc; // the cyclic components of the cross covariance matrix.
cyc=ccm; cyc=ccm-ccm.transpose();
tmp=ccm;
tmp.Transpose();
cyc-=tmp;
Matrix44x QQ; Matrix44x QQ;
QQ.SetZero(); QQ.SetZero();
@ -228,9 +218,7 @@ bool ComputeRigidMatchMatrix(Matrix44x &res,
RM[0][0]=-ccm.Trace(); RM[0][0]=-ccm.Trace();
RM[1][1]=-ccm.Trace(); RM[1][1]=-ccm.Trace();
RM[2][2]=-ccm.Trace(); RM[2][2]=-ccm.Trace();
RM+=ccm; RM += ccm + ccm.transpose();
ccm.Transpose();
RM+=ccm;
QQ[0][0] = ccm.Trace(); QQ[0][0] = ccm.Trace();
QQ[0][1] = D[0]; QQ[0][2] = D[1]; QQ[0][3] = D[2]; QQ[0][1] = D[0]; QQ[0][2] = D[1]; QQ[0][3] = D[2];
@ -260,7 +248,7 @@ bool ComputeRigidMatchMatrix(Matrix44x &res,
maxv=d[i]; maxv=d[i];
} }
// The corresponding eigenvector define the searched rotation, // The corresponding eigenvector define the searched rotation,
Matrix44x Rot; Matrix44x Rot;
q.ToMatrix(Rot); q.ToMatrix(Rot);
// the translation (last row) is simply the difference between the transformed src barycenter and the trg baricenter // the translation (last row) is simply the difference between the transformed src barycenter and the trg baricenter
tr= (bfix - Rot*bmov); tr= (bfix - Rot*bmov);

View File

@ -49,35 +49,31 @@ void RotationalPartByPolarDecomposition( const vcg::Matrix33<S> & m, vcg::Matrix
r.SetZero(); r.SetZero();
s.SetZero(); s.SetZero();
tmp= m; tmp = m*m.transpose();
tmp.Transpose();
tmp = m*tmp;
Matrix33<S> res; Matrix33<S> res;
Point3<S> e; Point3<S> e;
bool ss = SingularValueDecomposition<vcg::Matrix33<S> >(tmp,&e[0],res); bool ss = SingularValueDecomposition<vcg::Matrix33<S> >(tmp,&e[0],res);
res.Transpose();
e[0]=math::Sqrt(e[0]); e[0]=math::Sqrt(e[0]);
e[1]=math::Sqrt(e[1]); e[1]=math::Sqrt(e[1]);
e[2]=math::Sqrt(e[2]); e[2]=math::Sqrt(e[2]);
#ifdef VCG_USE_EIGEN #ifdef VCG_USE_EIGEN
tmp = tmp*e.asDiagonal()*res; tmp = tmp*e.asDiagonal()*res.transpose();
#else #else
tmp = tmp*Matrix33Diag<S>(e)*res; tmp = tmp*Matrix33Diag<S>(e)*res.transpose();
#endif #endif
bool s1 = SingularValueDecomposition<vcg::Matrix33<S> >(tmp,&e[0],res); bool s1 = SingularValueDecomposition<vcg::Matrix33<S> >(tmp,&e[0],res.transpose());
tmp.Transpose();
e[0]=1/e[0]; e[0]=1/e[0];
e[1]=1/e[1]; e[1]=1/e[1];
e[2]=1/e[2]; e[2]=1/e[2];
#ifdef VCG_USE_EIGEN #ifdef VCG_USE_EIGEN
tmp = res*e.asDiagonal()*tmp; tmp = res*e.asDiagonal()*tmp.transpose();
#else #else
tmp = res*Matrix33Diag<S>(e)*tmp; tmp = res*Matrix33Diag<S>(e)*tmp.transpose();
#endif #endif
r = m*tmp; r = m*tmp;

View File

@ -88,7 +88,7 @@ template< class PlaneType >
c = (ScalarType)p.Offset()*p.Offset(); c = (ScalarType)p.Offset()*p.Offset();
} }
void Zero() // Azzera la quadrica void SetZero() // Azzera la quadrica
{ {
a[0] = 0; a[0] = 0;
a[1] = 0; a[1] = 0;

View File

@ -184,9 +184,9 @@ template <class S> Quaternion<S> Quaternion<S>::operator*(const S &s) const {
template <class S> Quaternion<S> Quaternion<S>::operator*(const Quaternion &q) const { template <class S> Quaternion<S> Quaternion<S>::operator*(const Quaternion &q) const {
Point3<S> t1(V(1), V(2), V(3)); Point3<S> t1(V(1), V(2), V(3));
Point3<S> t2(q.V(1), q.V(2), q.V(3)); Point3<S> t2(q.V(1), q.V(2), q.V(3));
S d = t2 * t1; S d = t2.dot(t1);
Point3<S> t3 = t1 ^ t2; Point3<S> t3 = t1 ^ t2;
t1 *= q.V(0); t1 *= q.V(0);

View File

@ -191,7 +191,7 @@ template <class S,class RotationType> Matrix44<S> Similarity<S,RotationType>::Ma
rot.ToMatrix(r); rot.ToMatrix(r);
Matrix44<S> s = Matrix44<S>().SetScale(sca, sca, sca); Matrix44<S> s = Matrix44<S>().SetScale(sca, sca, sca);
Matrix44<S> t = Matrix44<S>().SetTranslate(tra[0], tra[1], tra[2]); Matrix44<S> t = Matrix44<S>().SetTranslate(tra[0], tra[1], tra[2]);
return s*r*t; // trans * scale * rot; return Matrix44<S>(s*r*t); // trans * scale * rot;
} }
template <class S,class RotationType> Matrix44<S> Similarity<S,RotationType>::InverseMatrix() const { template <class S,class RotationType> Matrix44<S> Similarity<S,RotationType>::InverseMatrix() const {

View File

@ -89,6 +89,7 @@ namespace vcg {
template <class T> template <class T>
class Color4 : public Point4<T> class Color4 : public Point4<T>
{ {
typedef Point4<T> Base;
public: public:
/// Constant for storing standard colors. /// Constant for storing standard colors.
/// Each color is stored in a simple in so that the bit pattern match with the one of Color4b. /// Each color is stored in a simple in so that the bit pattern match with the one of Color4b.
@ -121,22 +122,30 @@ public:
inline Color4 ( const Point4<T> &c) :Point4<T>(c) {}; inline Color4 ( const Point4<T> &c) :Point4<T>(c) {};
inline Color4 (){}; inline Color4 (){};
inline Color4 (ColorConstant cc); inline Color4 (ColorConstant cc);
#ifdef VCG_USE_EIGEN
template<typename OtherDerived>
inline Color4 (const Eigen::MatrixBase<OtherDerived>& other) : Base(other)
{
// TODO make sure the types are the same
}
#endif
template <class Q> template <class Q>
inline void Import(const Color4<Q> & b ) inline void Import(const Color4<Q> & b )
{ {
Point4<T>::_v[0] = T(b[0]); Point4<T>::V()[0] = T(b[0]);
Point4<T>::_v[1] = T(b[1]); Point4<T>::V()[1] = T(b[1]);
Point4<T>::_v[2] = T(b[2]); Point4<T>::V()[2] = T(b[2]);
Point4<T>::_v[3] = T(b[3]); Point4<T>::V()[3] = T(b[3]);
} }
template <class Q> template <class Q>
inline void Import(const Point4<Q> & b ) inline void Import(const Point4<Q> & b )
{ {
Point4<T>::_v[0] = T(b[0]); Point4<T>::V()[0] = T(b[0]);
Point4<T>::_v[1] = T(b[1]); Point4<T>::V()[1] = T(b[1]);
Point4<T>::_v[2] = T(b[2]); Point4<T>::V()[2] = T(b[2]);
Point4<T>::_v[3] = T(b[3]); Point4<T>::V()[3] = T(b[3]);
} }
template <class Q> template <class Q>
@ -150,7 +159,7 @@ public:
inline Color4 operator + ( const Color4 & p) const inline Color4 operator + ( const Color4 & p) const
{ {
return Color4( this->_v[0]+p._v[0], this->_v[1]+p._v[1], this->_v[2]+p._v[2], this->_v[3]+p._v[3] ); return Color4( (*this)[0]+p.V()[0], (*this)[1]+p.V()[1], (*this)[2]+p.V()[2], (*this)[3]+p.V()[3] );
} }
@ -161,20 +170,20 @@ public:
inline void SetRGB( unsigned char r, unsigned char g, unsigned char b ) inline void SetRGB( unsigned char r, unsigned char g, unsigned char b )
{ {
Point4<T>::_v[0] = r; Point4<T>::V()[0] = r;
Point4<T>::_v[1] = g; Point4<T>::V()[1] = g;
Point4<T>::_v[2] = b; Point4<T>::V()[2] = b;
Point4<T>::_v[3] = 0; Point4<T>::V()[3] = 0;
} }
void SetHSVColor( float h, float s, float v){ void SetHSVColor( float h, float s, float v){
float r,g,b; float r,g,b;
if(s==0.0){ // gray color if(s==0.0){ // gray color
r = g = b = v; r = g = b = v;
Point4<T>::_v[0]=(unsigned char)(255*r); Point4<T>::V()[0]=(unsigned char)(255*r);
Point4<T>::_v[1]=(unsigned char)(255*g); Point4<T>::V()[1]=(unsigned char)(255*g);
Point4<T>::_v[2]=(unsigned char)(255*b); Point4<T>::V()[2]=(unsigned char)(255*b);
Point4<T>::_v[3]=255; Point4<T>::V()[3]=255;
return; return;
} }
if(h==1.0) h = 0.0; if(h==1.0) h = 0.0;
@ -194,11 +203,11 @@ public:
case 4: r=t; g=p; b=v; break; case 4: r=t; g=p; b=v; break;
case 5: r=v; g=p; b=q; break; case 5: r=v; g=p; b=q; break;
} }
Point4<T>::_v[0]=(unsigned char)(255*r); Point4<T>::V()[0]=(unsigned char)(255*r);
Point4<T>::_v[1]=(unsigned char)(255*g); Point4<T>::V()[1]=(unsigned char)(255*g);
Point4<T>::_v[2]=(unsigned char)(255*b); Point4<T>::V()[2]=(unsigned char)(255*b);
Point4<T>::_v[3]=255; Point4<T>::V()[3]=255;
// _v[0]=r*256;_v[1]=g*256;_v[2]=b*256; // V()[0]=r*256;V()[1]=g*256;V()[2]=b*256;
} }
inline static Color4 GrayShade(float f) inline static Color4 GrayShade(float f)
@ -246,10 +255,10 @@ inline void Color4<T>::lerp(const Color4<T> &c0, const Color4<T> &c1, const floa
assert(x>=0); assert(x>=0);
assert(x<=1); assert(x<=1);
Point4<T>::_v[0]=(T)(c1._v[0]*x + c0._v[0]*(1.0f-x)); Point4<T>::V()[0]=(T)(c1.V()[0]*x + c0.V()[0]*(1.0f-x));
Point4<T>::_v[1]=(T)(c1._v[1]*x + c0._v[1]*(1.0f-x)); Point4<T>::V()[1]=(T)(c1.V()[1]*x + c0.V()[1]*(1.0f-x));
Point4<T>::_v[2]=(T)(c1._v[2]*x + c0._v[2]*(1.0f-x)); Point4<T>::V()[2]=(T)(c1.V()[2]*x + c0.V()[2]*(1.0f-x));
Point4<T>::_v[3]=(T)(c1._v[3]*x + c0._v[3]*(1.0f-x)); Point4<T>::V()[3]=(T)(c1.V()[3]*x + c0.V()[3]*(1.0f-x));
} }
template <class T> template <class T>
@ -257,10 +266,10 @@ inline void Color4<T>::lerp(const Color4<T> &c0, const Color4<T> &c1, const Colo
{ {
assert(fabs(ip[0]+ip[1]+ip[2]-1)<0.00001); assert(fabs(ip[0]+ip[1]+ip[2]-1)<0.00001);
Point4<T>::_v[0]=(T)(c0[0]*ip[0] + c1[0]*ip[1]+ c2[0]*ip[2]); Point4<T>::V()[0]=(T)(c0[0]*ip[0] + c1[0]*ip[1]+ c2[0]*ip[2]);
Point4<T>::_v[1]=(T)(c0[1]*ip[0] + c1[1]*ip[1]+ c2[1]*ip[2]); Point4<T>::V()[1]=(T)(c0[1]*ip[0] + c1[1]*ip[1]+ c2[1]*ip[2]);
Point4<T>::_v[2]=(T)(c0[2]*ip[0] + c1[2]*ip[1]+ c2[2]*ip[2]); Point4<T>::V()[2]=(T)(c0[2]*ip[0] + c1[2]*ip[1]+ c2[2]*ip[2]);
Point4<T>::_v[3]=(T)(c0[3]*ip[0] + c1[3]*ip[1]+ c2[3]*ip[2]); Point4<T>::V()[3]=(T)(c0[3]*ip[0] + c1[3]*ip[1]+ c2[3]*ip[2]);
} }
@ -292,10 +301,10 @@ template <>
template <> template <>
inline void Color4<float>::Import(const Color4<unsigned char> &b) inline void Color4<float>::Import(const Color4<unsigned char> &b)
{ {
this->_v[0]=b[0]/255.0f; (*this)[0]=b[0]/255.0f;
this->_v[1]=b[1]/255.0f; (*this)[1]=b[1]/255.0f;
this->_v[2]=b[2]/255.0f; (*this)[2]=b[2]/255.0f;
this->_v[3]=b[3]/255.0f; (*this)[3]=b[3]/255.0f;
} }
#if !defined(__GNUC__) || (__GNUC__ > 3) #if !defined(__GNUC__) || (__GNUC__ > 3)
@ -304,10 +313,10 @@ template <> // [Bug c++/14479] enum definition in template class with template m
template <> template <>
inline void Color4<unsigned char>::Import(const Color4<float> &b) inline void Color4<unsigned char>::Import(const Color4<float> &b)
{ {
this->_v[0]=(unsigned char)(b[0]*255.0f); (*this)[0]=(unsigned char)(b[0]*255.0f);
this->_v[1]=(unsigned char)(b[1]*255.0f); (*this)[1]=(unsigned char)(b[1]*255.0f);
this->_v[2]=(unsigned char)(b[2]*255.0f); (*this)[2]=(unsigned char)(b[2]*255.0f);
this->_v[3]=(unsigned char)(b[3]*255.0f); (*this)[3]=(unsigned char)(b[3]*255.0f);
} }
#if !defined(__GNUC__) || (__GNUC__ > 3) #if !defined(__GNUC__) || (__GNUC__ > 3)
@ -316,10 +325,10 @@ template <> // [Bug c++/14479] enum definition in template class with template m
template <> template <>
inline void Color4<unsigned char>::Import(const Point4<float> &b) inline void Color4<unsigned char>::Import(const Point4<float> &b)
{ {
this->_v[0]=(unsigned char)(b[0]*255.0f); (*this)[0]=(unsigned char)(b[0]*255.0f);
this->_v[1]=(unsigned char)(b[1]*255.0f); (*this)[1]=(unsigned char)(b[1]*255.0f);
this->_v[2]=(unsigned char)(b[2]*255.0f); (*this)[2]=(unsigned char)(b[2]*255.0f);
this->_v[3]=(unsigned char)(b[3]*255.0f); (*this)[3]=(unsigned char)(b[3]*255.0f);
} }
#if !defined(__GNUC__) || (__GNUC__ > 3) #if !defined(__GNUC__) || (__GNUC__ > 3)
@ -351,10 +360,10 @@ inline Color4<float> Color4<float>::Construct( const Color4<unsigned char> & b )
//template <class T,class S> //template <class T,class S>
//inline void Color4<T>::Import(const Color4<S> &b) //inline void Color4<T>::Import(const Color4<S> &b)
//{ //{
// _v[0] = T(b[0]); // V()[0] = T(b[0]);
// _v[1] = T(b[1]); // V()[1] = T(b[1]);
// _v[2] = T(b[2]); // V()[2] = T(b[2]);
// _v[3] = T(b[3]); // V()[3] = T(b[3]);
//} //}
// //
template<> template<>
@ -382,10 +391,10 @@ template<>
inline Color4<unsigned char> Color4<unsigned char>::operator + ( const Color4<unsigned char> & p) const inline Color4<unsigned char> Color4<unsigned char>::operator + ( const Color4<unsigned char> & p) const
{ {
return Color4<unsigned char>( return Color4<unsigned char>(
math::Clamp(int(this->_v[0])+int(p._v[0]),0,255), math::Clamp(int((*this)[0])+int(p[0]),0,255),
math::Clamp(int(this->_v[1])+int(p._v[1]),0,255), math::Clamp(int((*this)[1])+int(p[1]),0,255),
math::Clamp(int(this->_v[2])+int(p._v[2]),0,255), math::Clamp(int((*this)[2])+int(p[2]),0,255),
math::Clamp(int(this->_v[3])+int(p._v[3]),0,255) math::Clamp(int((*this)[3])+int(p[3]),0,255)
); );
} }

View File

@ -0,0 +1,572 @@
/****************************************************************************
* 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.26 2006/11/13 13:03:45 ponchio
Added GetBBox in Point3 (declaration) the body of the function is in box3.h
Revision 1.25 2006/10/13 12:59:24 cignoni
Added **explicit** constructor from three coords of a different scalartype
Revision 1.24 2006/09/28 13:37:35 m_di_benedetto
added non const * V()
Revision 1.23 2005/11/09 16:11:55 cignoni
Added Abs and LowClampToZero
Revision 1.22 2005/09/14 14:09:21 m_di_benedetto
Added specialized Convert() for the same scalar type.
Revision 1.21 2005/05/06 14:45:33 spinelli
cambiato parentesi nel costruttore di GetUV per rendere compatibile tale costruttore con MVC e borland
Revision 1.20 2005/04/27 16:05:19 callieri
line 466, added parentesis on default value creator getUV [borland]
Revision 1.19 2004/11/09 15:49:07 ganovelli
added GetUV
Revision 1.18 2004/10/13 12:45:51 cignoni
Better Doxygen documentation
Revision 1.17 2004/09/10 14:01:40 cignoni
Added polar to cartesian
Revision 1.16 2004/03/21 17:14:56 ponchio
Added a math::
Revision 1.15 2004/03/07 22:45:32 cignoni
Moved quality and normal functions to the triangle class.
Revision 1.14 2004/03/05 17:55:01 tarini
errorino: upper case in Zero()
Revision 1.13 2004/03/03 14:22:48 cignoni
Yet against cr lf mismatch
Revision 1.12 2004/02/23 23:42:26 cignoni
Translated comments, removed unusued stuff. corrected linefeed/cr
Revision 1.11 2004/02/19 16:12:28 cignoni
cr lf mismatch 2
Revision 1.10 2004/02/19 16:06:24 cignoni
cr lf mismatch
Revision 1.8 2004/02/19 15:13:40 cignoni
corrected sqrt and added doxygen groups
Revision 1.7 2004/02/17 02:08:47 cignoni
Di prova...
Revision 1.6 2004/02/15 23:35:47 cignoni
Cambiato nome type template in accordo alla styleguide
Revision 1.5 2004/02/10 01:07:15 cignoni
Edited Comments and GPL license
Revision 1.4 2004/02/09 13:48:02 cignoni
Edited doxygen comments
****************************************************************************/
#ifndef __VCGLIB_POINT3
#define __VCGLIB_POINT3
#include <assert.h>
#include <vcg/math/base.h>
namespace vcg {
/** \addtogroup space */
/*@{*/
/**
The templated class for representing a point in 3D space.
The class is templated over the ScalarType class that is used to represent coordinates. All the usual
operator overloading (* + - ...) is present.
*/
template <class T> class Box3;
template <class P3ScalarType> class Point3
{
protected:
/// The only data member. Hidden to user.
P3ScalarType _v[3];
public:
typedef P3ScalarType ScalarType;
enum {Dimension = 3};
//@{
/** @name Standard Constructors and Initializers
No casting operators have been introduced to avoid automatic unattended (and costly) conversion between different point types
**/
inline Point3 () { }
inline Point3 ( const P3ScalarType nx, const P3ScalarType ny, const P3ScalarType nz )
{
_v[0] = nx;
_v[1] = ny;
_v[2] = nz;
}
inline Point3 ( Point3 const & p )
{
_v[0]= p._v[0];
_v[1]= p._v[1];
_v[2]= p._v[2];
}
inline Point3 ( const P3ScalarType nv[3] )
{
_v[0] = nv[0];
_v[1] = nv[1];
_v[2] = nv[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 void SetZero()
{
_v[0] = 0;
_v[1] = 0;
_v[2] = 0;
}
/// 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 P3ScalarType Ext( const int i ) const
{
if(i>=0 && i<=2) return _v[i];
else return 0;
}
template <class Q>
inline void Import( const Point3<Q> & b )
{
_v[0] = P3ScalarType(b[0]);
_v[1] = P3ScalarType(b[1]);
_v[2] = P3ScalarType(b[2]);
}
template <class Q>
static inline Point3 Construct( const Point3<Q> & b )
{
return Point3(P3ScalarType(b[0]),P3ScalarType(b[1]),P3ScalarType(b[2]));
}
template <class Q>
static inline Point3 Construct( const Q & P0, const Q & P1, const Q & P2)
{
return Point3(P3ScalarType(P0),P3ScalarType(P1),P3ScalarType(P2));
}
static inline Point3 Construct( const Point3<ScalarType> & b )
{
return b;
}
//@}
//@{
/** @name Data Access.
access to data is done by overloading of [] or explicit naming of coords (x,y,z)**/
inline P3ScalarType & operator [] ( const int i )
{
assert(i>=0 && i<3);
return _v[i];
}
inline const P3ScalarType & operator [] ( const int i ) const
{
assert(i>=0 && i<3);
return _v[i];
}
inline const P3ScalarType &X() const { return _v[0]; }
inline const P3ScalarType &Y() const { return _v[1]; }
inline const P3ScalarType &Z() const { return _v[2]; }
inline P3ScalarType &X() { return _v[0]; }
inline P3ScalarType &Y() { return _v[1]; }
inline P3ScalarType &Z() { return _v[2]; }
inline const P3ScalarType * V() const
{
return _v;
}
inline P3ScalarType * V()
{
return _v;
}
inline P3ScalarType & V( const int i )
{
assert(i>=0 && i<3);
return _v[i];
}
inline const P3ScalarType & V( const int i ) const
{
assert(i>=0 && i<3);
return _v[i];
}
//@}
//@{
/** @name Classical overloading of operators
Note
**/
inline Point3 operator + ( Point3 const & p) const
{
return Point3<P3ScalarType>( _v[0]+p._v[0], _v[1]+p._v[1], _v[2]+p._v[2] );
}
inline Point3 operator - ( Point3 const & p) const
{
return Point3<P3ScalarType>( _v[0]-p._v[0], _v[1]-p._v[1], _v[2]-p._v[2] );
}
inline Point3 operator * ( const P3ScalarType s ) const
{
return Point3<P3ScalarType>( _v[0]*s, _v[1]*s, _v[2]*s );
}
inline Point3 operator / ( const P3ScalarType s ) const
{
return Point3<P3ScalarType>( _v[0]/s, _v[1]/s, _v[2]/s );
}
/// Dot product
inline P3ScalarType operator * ( Point3 const & p ) const
{
return ( _v[0]*p._v[0] + _v[1]*p._v[1] + _v[2]*p._v[2] );
}
inline P3ScalarType dot( const Point3 & p ) const { return (*this) * p; }
/// Cross product
inline Point3 operator ^ ( Point3 const & p ) const
{
return Point3 <P3ScalarType>
(
_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]
);
}
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 P3ScalarType s )
{
_v[0] *= s;
_v[1] *= s;
_v[2] *= s;
return *this;
}
inline Point3 & operator /= ( const P3ScalarType s )
{
_v[0] /= s;
_v[1] /= s;
_v[2] /= s;
return *this;
}
// Norme
inline P3ScalarType Norm() const
{
return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] );
}
inline P3ScalarType SquaredNorm() const
{
return ( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] );
}
// Scalatura differenziata
inline Point3 & Scale( const P3ScalarType sx, const P3ScalarType sy, const P3ScalarType sz )
{
_v[0] *= sx;
_v[1] *= sy;
_v[2] *= sz;
return *this;
}
inline Point3 & Scale( const Point3 & p )
{
_v[0] *= p._v[0];
_v[1] *= p._v[1];
_v[2] *= p._v[2];
return *this;
}
// Normalizzazione
inline Point3 & Normalize()
{
P3ScalarType n = math::Sqrt(_v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2]);
if(n>0.0) { _v[0] /= n; _v[1] /= n; _v[2] /= n; }
return *this;
}
// for compatibility with eigen port
inline Point3 & normalized() { return Normalize(); }
/**
* Convert to polar coordinates from cartesian coordinates.
*
* Theta is the azimuth angle and ranges between [0, 360) degrees.
* Phi is the elevation angle (not the polar angle) and ranges between [-90, 90] degrees.
*
* /note Note that instead of the classical polar angle, which ranges between
* 0 and 180 degrees we opt for the elevation angle to obtain a more
* intuitive spherical coordinate system.
*/
void ToPolar(P3ScalarType &ro, P3ScalarType &theta, P3ScalarType &phi) const
{
ro = Norm();
theta = (P3ScalarType)atan2(_v[2], _v[0]);
phi = (P3ScalarType)asin(_v[1]/ro);
}
/**
* Convert from polar coordinates to cartesian coordinates.
*
* Theta is the azimuth angle and ranges between [0, 360) degrees.
* Phi is the elevation angle (not the polar angle) and ranges between [-90, 90] degrees.
*
* \note Note that instead of the classical polar angle, which ranges between
* 0 and 180 degrees, we opt for the elevation angle to obtain a more
* intuitive spherical coordinate system.
*/
void FromPolar(const P3ScalarType &ro, const P3ScalarType &theta, const P3ScalarType &phi)
{
_v[0]= ro*cos(theta)*cos(phi);
_v[1]= ro*sin(phi);
_v[2]= ro*sin(theta)*cos(phi);
}
Box3<P3ScalarType> GetBBox(Box3<P3ScalarType> &bb) const;
//@}
//@{
/** @name Comparison Operators.
Note that the reverse z prioritized ordering, useful in many situations.
**/
inline bool operator == ( Point3 const & p ) const
{
return _v[0]==p._v[0] && _v[1]==p._v[1] && _v[2]==p._v[2];
}
inline bool operator != ( Point3 const & p ) const
{
return _v[0]!=p._v[0] || _v[1]!=p._v[1] || _v[2]!=p._v[2];
}
inline bool operator < ( Point3 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 > ( Point3 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 <= ( Point3 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 >= ( Point3 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 Point3 operator - () const
{
return Point3<P3ScalarType> ( -_v[0], -_v[1], -_v[2] );
}
//@}
}; // end class definition
template <class P3ScalarType>
inline P3ScalarType Angle( Point3<P3ScalarType> const & p1, Point3<P3ScalarType> const & p2 )
{
P3ScalarType w = p1.Norm()*p2.Norm();
if(w==0) return -1;
P3ScalarType t = (p1*p2)/w;
if(t>1) t = 1;
else if(t<-1) t = -1;
return (P3ScalarType) acos(t);
}
// versione uguale alla precedente ma che assume che i due vettori sono unitari
template <class P3ScalarType>
inline P3ScalarType AngleN( Point3<P3ScalarType> const & p1, Point3<P3ScalarType> const & p2 )
{
P3ScalarType w = p1*p2;
if(w>1)
w = 1;
else if(w<-1)
w=-1;
return (P3ScalarType) acos(w);
}
template <class P3ScalarType>
inline P3ScalarType Norm( Point3<P3ScalarType> const & p )
{
return p.Norm();
}
template <class P3ScalarType>
inline P3ScalarType SquaredNorm( Point3<P3ScalarType> const & p )
{
return p.SquaredNorm();
}
template <class P3ScalarType>
inline Point3<P3ScalarType> & Normalize( Point3<P3ScalarType> & p )
{
p.Normalize();
return p;
}
template <class P3ScalarType>
inline P3ScalarType Distance( Point3<P3ScalarType> const & p1,Point3<P3ScalarType> const & p2 )
{
return (p1-p2).Norm();
}
template <class P3ScalarType>
inline P3ScalarType SquaredDistance( Point3<P3ScalarType> const & p1,Point3<P3ScalarType> const & p2 )
{
return (p1-p2).SquaredNorm();
}
// Dot product preciso numericamente (solo double!!)
// Implementazione: si sommano i prodotti per ordine di esponente
// (prima le piu' grandi)
template<class P3ScalarType>
double stable_dot ( Point3<P3ScalarType> const & p0, Point3<P3ScalarType> const & p1 )
{
P3ScalarType k0 = p0._v[0]*p1._v[0];
P3ScalarType k1 = p0._v[1]*p1._v[1];
P3ScalarType k2 = p0._v[2]*p1._v[2];
int exp0,exp1,exp2;
frexp( double(k0), &exp0 );
frexp( double(k1), &exp1 );
frexp( double(k2), &exp2 );
if( exp0<exp1 )
{
if(exp0<exp2)
return (k1+k2)+k0;
else
return (k0+k1)+k2;
}
else
{
if(exp1<exp2)
return(k0+k2)+k1;
else
return (k0+k1)+k2;
}
}
/// Point(p) Edge(v1-v2) dist, q is the point in v1-v2 with min dist
template<class P3ScalarType>
P3ScalarType PSDist( const Point3<P3ScalarType> & p,
const Point3<P3ScalarType> & v1,
const Point3<P3ScalarType> & v2,
Point3<P3ScalarType> & q )
{
Point3<P3ScalarType> e = v2-v1;
P3ScalarType t = ((p-v1)*e)/e.SquaredNorm();
if(t<0) t = 0;
else if(t>1) t = 1;
q = v1+e*t;
return Distance(p,q);
}
template <class P3ScalarType>
void GetUV( Point3<P3ScalarType> &n,Point3<P3ScalarType> &u, Point3<P3ScalarType> &v, Point3<P3ScalarType> up=(Point3<P3ScalarType>(0,1,0)) )
{
n.Normalize();
const double LocEps=double(1e-7);
u=n^up;
double len = u.Norm();
if(len < LocEps)
{
if(fabs(n[0])<fabs(n[1])){
if(fabs(n[0])<fabs(n[2])) up=Point3<P3ScalarType>(1,0,0); // x is the min
else up=Point3<P3ScalarType>(0,0,1); // z is the min
}else {
if(fabs(n[1])<fabs(n[2])) up=Point3<P3ScalarType>(0,1,0); // y is the min
else up=Point3<P3ScalarType>(0,0,1); // z is the min
}
u=n^up;
}
u.Normalize();
v=n^u;
v.Normalize();
Point3<P3ScalarType> uv=u^v;
}
template <class SCALARTYPE>
inline Point3<SCALARTYPE> Abs(const Point3<SCALARTYPE> & p) {
return (Point3<SCALARTYPE>(math::Abs(p[0]), math::Abs(p[1]), math::Abs(p[2])));
}
// probably a more uniform naming should be defined...
template <class SCALARTYPE>
inline Point3<SCALARTYPE> LowClampToZero(const Point3<SCALARTYPE> & p) {
return (Point3<SCALARTYPE>(math::Max(p[0], (SCALARTYPE)0), math::Max(p[1], (SCALARTYPE)0), math::Max(p[2], (SCALARTYPE)0)));
}
typedef Point3<short> Point3s;
typedef Point3<int> Point3i;
typedef Point3<float> Point3f;
typedef Point3<double> Point3d;
/*@}*/
} // end namespace
#endif

View File

@ -0,0 +1,383 @@
/****************************************************************************
* 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.12 2006/06/21 11:06:16 ganovelli
changed return type of Zero() (to void)
Revision 1.11 2005/04/13 09:40:30 ponchio
Including math/bash.h
Revision 1.10 2005/03/18 16:34:42 fiorin
minor changes to comply gcc compiler
Revision 1.9 2005/01/21 18:02:11 ponchio
Removed dependence from matrix44 and changed VectProd
Revision 1.8 2005/01/12 11:25:02 ganovelli
added Dimension
Revision 1.7 2004/10/11 17:46:11 ganovelli
added definition of vector product (not implemented)
Revision 1.6 2004/05/10 11:16:19 ganovelli
include assert.h added
Revision 1.5 2004/03/31 10:09:58 cignoni
missing return value in zero()
Revision 1.4 2004/03/11 17:17:49 tarini
added commets (doxy), uniformed with new style, now using math::, ...
added HomoNormalize(), Zero()... remade StableDot() (hand made sort).
Revision 1.1 2004/02/10 01:11:28 cignoni
Edited Comments and GPL license
****************************************************************************/
#ifndef __VCGLIB_POINT4
#define __VCGLIB_POINT4
#include <assert.h>
#include <vcg/math/base.h>
namespace vcg {
/** \addtogroup space */
/*@{*/
/**
The templated class for representing a point in 4D space.
The class is templated over the ScalarType class that is used to represent coordinates.
All the usual operator (* + - ...) are defined.
*/
template <class T> class Point4
{
public:
/// The only data member. Hidden to user.
T _v[4];
public:
typedef T ScalarType;
enum {Dimension = 4};
//@{
/** @name Standard Constructors and Initializers
No casting operators have been introduced to avoid automatic unattended (and costly) conversion between different point types
**/
inline Point4 () { }
inline Point4 ( const T nx, const T ny, const T nz , const T nw )
{
_v[0] = nx; _v[1] = ny; _v[2] = nz; _v[3] = nw;
}
inline Point4 ( const T p[4] )
{
_v[0] = p[0]; _v[1]= p[1]; _v[2] = p[2]; _v[3]= p[3];
}
inline Point4 ( const Point4 & p )
{
_v[0]= p._v[0]; _v[1]= p._v[1]; _v[2]= p._v[2]; _v[3]= p._v[3];
}
inline void Zero()
{
_v[0] = _v[1] = _v[2] = _v[3]= 0;
}
template <class Q>
/// importer from different Point4 types
inline void Import( const Point4<Q> & b )
{
_v[0] = T(b[0]); _v[1] = T(b[1]);
_v[2] = T(b[2]);
_v[3] = T(b[3]);
}
/// constuctor that imports from different Point4 types
template <class Q>
static inline Point4 Construct( const Point4<Q> & b )
{
return Point4(T(b[0]),T(b[1]),T(b[2]),T(b[3]));
}
//@}
//@{
/** @name Data Access.
access to data is done by overloading of [] or explicit naming of coords (x,y,z,w)
**/
inline const T & operator [] ( const int i ) const
{
assert(i>=0 && i<4);
return _v[i];
}
inline T & operator [] ( const int i )
{
assert(i>=0 && i<4);
return _v[i];
}
inline T &X() {return _v[0];}
inline T &Y() {return _v[1];}
inline T &Z() {return _v[2];}
inline T &W() {return _v[3];}
inline T const * V() const
{
return _v;
}
inline const T & V ( const int i ) const
{
assert(i>=0 && i<4);
return _v[i];
}
inline T & V ( const int i )
{
assert(i>=0 && i<4);
return _v[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 _v[i];
else return 0;
}
//@}
//@{
/** @name Linear operators and the likes
**/
inline Point4 operator + ( const Point4 & 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 Point4 & 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 T s ) const
{
return Point4( _v[0]*s, _v[1]*s, _v[2]*s, _v[3]*s );
}
inline Point4 operator / ( const T s ) const
{
return Point4( _v[0]/s, _v[1]/s, _v[2]/s, _v[3]/s );
}
inline Point4 & operator += ( const Point4 & 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 Point4 & 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 T s )
{
_v[0] *= s; _v[1] *= s; _v[2] *= s; _v[3] *= s;
return *this;
}
inline Point4 & operator /= ( const T s )
{
_v[0] /= s; _v[1] /= s; _v[2] /= s; _v[3] /= s;
return *this;
}
inline Point4 operator - () const
{
return Point4( -_v[0], -_v[1], -_v[2], -_v[3] );
}
inline Point4 VectProd ( const Point4 &x, const Point4 &z ) const
{
Point4 res;
const Point4 &y = *this;
res[0] = y[1]*x[2]*z[3]-y[1]*x[3]*z[2]-x[1]*y[2]*z[3]+
x[1]*y[3]*z[2]+z[1]*y[2]*x[3]-z[1]*y[3]*x[2];
res[1] = y[0]*x[3]*z[2]-z[0]*y[2]*x[3]-y[0]*x[2]*
z[3]+z[0]*y[3]*x[2]+x[0]*y[2]*z[3]-x[0]*y[3]*z[2];
res[2] = -y[0]*z[1]*x[3]+x[0]*z[1]*y[3]+y[0]*x[1]*
z[3]-x[0]*y[1]*z[3]-z[0]*x[1]*y[3]+z[0]*y[1]*x[3];
res[3] = -z[0]*y[1]*x[2]-y[0]*x[1]*z[2]+x[0]*y[1]*
z[2]+y[0]*z[1]*x[2]-x[0]*z[1]*y[2]+z[0]*x[1]*y[2];
return res;
}
//@}
//@{
/** @name Norms and normalizations
**/
/// Euclidian normal
inline T Norm() const
{
return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3] );
}
/// Squared euclidian normal
inline T SquaredNorm() const
{
return _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3];
}
/// Euclidian normalization
inline Point4 & Normalize()
{
T n = sqrt(_v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3] );
if(n>0.0) { _v[0] /= n; _v[1] /= n; _v[2] /= n; _v[3] /= n; }
return *this;
}
/// Homogeneous normalization (division by W)
inline Point4 & HomoNormalize(){
if (_v[3]!=0.0) { _v[0] /= _v[3]; _v[1] /= _v[3]; _v[2] /= _v[3]; _v[3]=1.0; }
return *this;
};
//@}
//@{
/** @name Comparison operators (lexicographical order)
**/
inline bool operator == ( const Point4& 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 != ( const Point4 & 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 < ( Point4 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 > ( const Point4 & 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 <= ( const Point4 & 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 >= ( const Point4 & 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]);
}
//@}
//@{
/** @name Dot products
**/
// dot product
inline T operator * ( const Point4 & p ) const
{
return _v[0]*p._v[0] + _v[1]*p._v[1] + _v[2]*p._v[2] + _v[3]*p._v[3];
}
inline T dot( const Point4 & p ) const { return (*this) * p; }
inline Point4 operator ^ ( const Point4& p ) const
{
assert(0);// not defined by two vectors (only put for metaprogramming)
return Point4();
}
/// slower version, more stable (double precision only)
T StableDot ( const Point4<T> & p ) const
{
T 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;
}
//@}
}; // end class definition
template <class T>
T Angle( const Point4<T>& p1, const Point4<T> & p2 )
{
T w = p1.Norm()*p2.Norm();
if(w==0) return -1;
T t = (p1*p2)/w;
if(t>1) t=1;
return T( math::Acos(t) );
}
template <class T>
inline T Norm( const Point4<T> & p )
{
return p.Norm();
}
template <class T>
inline T SquaredNorm( const Point4<T> & p )
{
return p.SquaredNorm();
}
template <class T>
inline T Distance( const Point4<T> & p1, const Point4<T> & p2 )
{
return Norm(p1-p2);
}
template <class T>
inline T SquaredDistance( const Point4<T> & p1, const Point4<T> & p2 )
{
return SquaredNorm(p1-p2);
}
/// slower version of dot product, more stable (double precision only)
template<class T>
double StableDot ( Point4<T> const & p0, Point4<T> const & p1 )
{
return p0.StableDot(p1);
}
typedef Point4<short> Point4s;
typedef Point4<int> Point4i;
typedef Point4<float> Point4f;
typedef Point4<double> Point4d;
/*@}*/
} // end namespace
#endif

View File

@ -339,10 +339,10 @@ namespace vcg {
inline bool IntersectionLinePlane( const Plane3<T> & pl, const Line3<T> & li, Point3<T> & po){ inline bool IntersectionLinePlane( const Plane3<T> & pl, const Line3<T> & li, Point3<T> & po){
const T epsilon = T(1e-8); const T epsilon = T(1e-8);
T k = pl.Direction() * li.Direction(); // Compute 'k' factor T k = pl.Direction().dot(li.Direction()); // Compute 'k' factor
if( (k > -epsilon) && (k < epsilon)) if( (k > -epsilon) && (k < epsilon))
return false; return false;
T r = (pl.Offset() - pl.Direction()*li.Origin())/k; // Compute ray distance T r = (pl.Offset() - pl.Direction().dot(li.Origin()))/k; // Compute ray distance
po = li.Origin() + li.Direction()*r; po = li.Origin() + li.Direction()*r;
return true; return true;
} }

View File

@ -121,8 +121,8 @@ public:
{ return _ori!=p._ori || _dir!=p._dir; } { return _ori!=p._ori || _dir!=p._dir; }
/// Projects a point on the line /// Projects a point on the line
inline ScalarType Projection( const PointType &p ) const inline ScalarType Projection( const PointType &p ) const
{ if (NORM) return ScalarType((p-_ori)*_dir); { if (NORM) return ScalarType((p-_ori).dot(_dir));
else return ScalarType((p-_ori)*_dir/_dir.SquaredNorm()); else return ScalarType((p-_ori).dot(_dir)/_dir.SquaredNorm());
} }
/// returns wheter this type is normalized or not /// returns wheter this type is normalized or not
static bool IsNormalized() {return NORM;}; static bool IsNormalized() {return NORM;};

View File

@ -141,7 +141,7 @@ public:
///Project a point on the plane ///Project a point on the plane
PointType Projection(const PointType &p) const { PointType Projection(const PointType &p) const {
ScalarType k = p * _dir - _offset; ScalarType k = p.dot(_dir) - _offset;
return p - _dir * k; return p - _dir * k;
} }
@ -154,13 +154,13 @@ public:
void Init(const PointType &p0, const PointType &p1, const PointType &p2) { void Init(const PointType &p0, const PointType &p1, const PointType &p2) {
_dir = (p2 - p0) ^ (p1 - p0); _dir = (p2 - p0) ^ (p1 - p0);
if(NORM) Normalize(); if(NORM) Normalize();
_offset = p0 * _dir; _offset = p0.dot(_dir);
} }
/// Calculates the plane passing through a point and the normal (Rename this method /// Calculates the plane passing through a point and the normal (Rename this method
inline void Init(const PointType &p0, const PointType &norm) { inline void Init(const PointType &p0, const PointType &norm) {
_dir = norm; _dir = norm;
_offset = p0 * _dir; _offset = p0.dot(_dir);
} }
}; // end class Plane3 }; // end class Plane3
@ -169,12 +169,12 @@ typedef Plane3<double> Plane3d;
///Distance plane - point (Move this function to somewhere else) ///Distance plane - point (Move this function to somewhere else)
template<class T> T Distance(const Plane3<T> &plane, const Point3<T> &point) { template<class T> T Distance(const Plane3<T> &plane, const Point3<T> &point) {
return plane.Direction() * point - plane.Offset(); return plane.Direction().dot(point) - plane.Offset();
} }
///Distance point-plane (Move this function to somewhere else) ///Distance point-plane (Move this function to somewhere else)
template<class T> T Distance(const Point3<T> &point, const Plane3<T> &plane) { template<class T> T Distance(const Point3<T> &point, const Plane3<T> &plane) {
return plane.Direction() * point - plane.Offset(); return plane.Direction().dot(point) - plane.Offset();
} }
} // end namespace } // end namespace

View File

@ -20,83 +20,26 @@
* for more details. * * for more details. *
* * * *
****************************************************************************/ ****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $ #ifndef VCG_USE_EIGEN
Revision 1.26 2006/11/13 13:03:45 ponchio #include "deprecated_point3.h"
Added GetBBox in Point3 (declaration) the body of the function is in box3.h #else
Revision 1.25 2006/10/13 12:59:24 cignoni
Added **explicit** constructor from three coords of a different scalartype
Revision 1.24 2006/09/28 13:37:35 m_di_benedetto
added non const * V()
Revision 1.23 2005/11/09 16:11:55 cignoni
Added Abs and LowClampToZero
Revision 1.22 2005/09/14 14:09:21 m_di_benedetto
Added specialized Convert() for the same scalar type.
Revision 1.21 2005/05/06 14:45:33 spinelli
cambiato parentesi nel costruttore di GetUV per rendere compatibile tale costruttore con MVC e borland
Revision 1.20 2005/04/27 16:05:19 callieri
line 466, added parentesis on default value creator getUV [borland]
Revision 1.19 2004/11/09 15:49:07 ganovelli
added GetUV
Revision 1.18 2004/10/13 12:45:51 cignoni
Better Doxygen documentation
Revision 1.17 2004/09/10 14:01:40 cignoni
Added polar to cartesian
Revision 1.16 2004/03/21 17:14:56 ponchio
Added a math::
Revision 1.15 2004/03/07 22:45:32 cignoni
Moved quality and normal functions to the triangle class.
Revision 1.14 2004/03/05 17:55:01 tarini
errorino: upper case in Zero()
Revision 1.13 2004/03/03 14:22:48 cignoni
Yet against cr lf mismatch
Revision 1.12 2004/02/23 23:42:26 cignoni
Translated comments, removed unusued stuff. corrected linefeed/cr
Revision 1.11 2004/02/19 16:12:28 cignoni
cr lf mismatch 2
Revision 1.10 2004/02/19 16:06:24 cignoni
cr lf mismatch
Revision 1.8 2004/02/19 15:13:40 cignoni
corrected sqrt and added doxygen groups
Revision 1.7 2004/02/17 02:08:47 cignoni
Di prova...
Revision 1.6 2004/02/15 23:35:47 cignoni
Cambiato nome type template in accordo alla styleguide
Revision 1.5 2004/02/10 01:07:15 cignoni
Edited Comments and GPL license
Revision 1.4 2004/02/09 13:48:02 cignoni
Edited doxygen comments
****************************************************************************/
#ifndef __VCGLIB_POINT3 #ifndef __VCGLIB_POINT3
#define __VCGLIB_POINT3 #define __VCGLIB_POINT3
#include <assert.h> #include "../math/eigen.h"
#include <vcg/math/base.h> #include <vcg/math/base.h>
namespace vcg{
template<class Scalar> class Point3;
}
namespace Eigen{
template<typename Scalar>
struct ei_traits<vcg::Point3<Scalar> > : ei_traits<Eigen::Matrix<Scalar,3,1> > {};
}
namespace vcg { namespace vcg {
/** \addtogroup space */ /** \addtogroup space */
@ -108,14 +51,22 @@ namespace vcg {
*/ */
template <class T> class Box3; template <class T> class Box3;
template <class P3ScalarType> class Point3 template <class _Scalar> class Point3 : public Eigen::Matrix<_Scalar,3,1>
{ {
protected: typedef Eigen::Matrix<_Scalar,3,1> _Base;
/// The only data member. Hidden to user. using _Base::coeff;
P3ScalarType _v[3]; using _Base::coeffRef;
using _Base::setZero;
using _Base::data;
using _Base::V;
public: public:
typedef P3ScalarType ScalarType;
_EIGEN_GENERIC_PUBLIC_INTERFACE(Point3,_Base);
typedef Scalar ScalarType;
VCG_EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Point3)
enum {Dimension = 3}; enum {Dimension = 3};
@ -125,63 +76,40 @@ public:
No casting operators have been introduced to avoid automatic unattended (and costly) conversion between different point types No casting operators have been introduced to avoid automatic unattended (and costly) conversion between different point types
**/ **/
inline Point3 () { } inline Point3 () {}
inline Point3 ( const P3ScalarType nx, const P3ScalarType ny, const P3ScalarType nz ) inline Point3 ( const Scalar nx, const Scalar ny, const Scalar nz ) : Base(nx,ny,nz) {}
{ inline Point3 ( Point3 const & p ) : Base(p) {}
_v[0] = nx; inline Point3 ( const Scalar nv[3] ) : Base(nv) {}
_v[1] = ny; template<typename OtherDerived>
_v[2] = nz; inline Point3(const Eigen::MatrixBase<OtherDerived>& other) : Base(other) {}
}
inline Point3 ( Point3 const & p )
{
_v[0]= p._v[0];
_v[1]= p._v[1];
_v[2]= p._v[2];
}
inline Point3 ( const P3ScalarType nv[3] )
{
_v[0] = nv[0];
_v[1] = nv[1];
_v[2] = nv[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 void SetZero()
{
_v[0] = 0;
_v[1] = 0;
_v[2] = 0;
}
/// Padding function: give a default 0 value to all the elements that are not in the [0..2] range. /// 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 /// Useful for managing in a consistent way object that could have point2 / point3 / point4
inline P3ScalarType Ext( const int i ) const inline Scalar Ext( const int i ) const
{ {
if(i>=0 && i<=2) return _v[i]; if(i>=0 && i<=2) return data()[i];
else return 0; else return 0;
} }
template <class Q> template<class OtherDerived>
inline void Import( const Point3<Q> & b ) inline void Import( const Eigen::MatrixBase<OtherDerived>& b )
{ {
_v[0] = P3ScalarType(b[0]); EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,3);
_v[1] = P3ScalarType(b[1]); data()[0] = Scalar(b[0]);
_v[2] = P3ScalarType(b[2]); data()[1] = Scalar(b[1]);
data()[2] = Scalar(b[2]);
} }
template <class Q> template <class Q>
static inline Point3 Construct( const Point3<Q> & b ) static inline Point3 Construct( const Point3<Q> & b )
{ {
return Point3(P3ScalarType(b[0]),P3ScalarType(b[1]),P3ScalarType(b[2])); return Point3(Scalar(b[0]),Scalar(b[1]),Scalar(b[2]));
} }
template <class Q> template <class Q>
static inline Point3 Construct( const Q & P0, const Q & P1, const Q & P2) static inline Point3 Construct( const Q & P0, const Q & P1, const Q & P2)
{ {
return Point3(P3ScalarType(P0),P3ScalarType(P1),P3ScalarType(P2)); return Point3(Scalar(P0),Scalar(P1),Scalar(P2));
} }
static inline Point3 Construct( const Point3<ScalarType> & b ) static inline Point3 Construct( const Point3<ScalarType> & b )
@ -196,39 +124,21 @@ public:
/** @name Data Access. /** @name Data Access.
access to data is done by overloading of [] or explicit naming of coords (x,y,z)**/ access to data is done by overloading of [] or explicit naming of coords (x,y,z)**/
inline P3ScalarType & operator [] ( const int i ) inline const Scalar &X() const { return data()[0]; }
inline const Scalar &Y() const { return data()[1]; }
inline const Scalar &Z() const { return data()[2]; }
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); assert(i>=0 && i<3);
return _v[i]; return data()[i];
} }
inline const P3ScalarType & operator [] ( const int i ) const inline const Scalar & V( const int i ) const
{ {
assert(i>=0 && i<3); assert(i>=0 && i<3);
return _v[i]; return data()[i];
}
inline const P3ScalarType &X() const { return _v[0]; }
inline const P3ScalarType &Y() const { return _v[1]; }
inline const P3ScalarType &Z() const { return _v[2]; }
inline P3ScalarType &X() { return _v[0]; }
inline P3ScalarType &Y() { return _v[1]; }
inline P3ScalarType &Z() { return _v[2]; }
inline const P3ScalarType * V() const
{
return _v;
}
inline P3ScalarType * V()
{
return _v;
}
inline P3ScalarType & V( const int i )
{
assert(i>=0 && i<3);
return _v[i];
}
inline const P3ScalarType & V( const int i ) const
{
assert(i>=0 && i<3);
return _v[i];
} }
//@} //@}
//@{ //@{
@ -237,96 +147,19 @@ public:
Note Note
**/ **/
inline Point3 operator + ( Point3 const & p) const // Scalatura differenziata
inline Point3 & Scale( const Scalar sx, const Scalar sy, const Scalar sz )
{ {
return Point3<P3ScalarType>( _v[0]+p._v[0], _v[1]+p._v[1], _v[2]+p._v[2] ); data()[0] *= sx;
} data()[1] *= sy;
inline Point3 operator - ( Point3 const & p) const data()[2] *= sz;
{
return Point3<P3ScalarType>( _v[0]-p._v[0], _v[1]-p._v[1], _v[2]-p._v[2] );
}
inline Point3 operator * ( const P3ScalarType s ) const
{
return Point3<P3ScalarType>( _v[0]*s, _v[1]*s, _v[2]*s );
}
inline Point3 operator / ( const P3ScalarType s ) const
{
return Point3<P3ScalarType>( _v[0]/s, _v[1]/s, _v[2]/s );
}
/// Dot product
inline P3ScalarType operator * ( Point3 const & p ) const
{
return ( _v[0]*p._v[0] + _v[1]*p._v[1] + _v[2]*p._v[2] );
}
/// Cross product
inline Point3 operator ^ ( Point3 const & p ) const
{
return Point3 <P3ScalarType>
(
_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]
);
}
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 P3ScalarType s )
{
_v[0] *= s;
_v[1] *= s;
_v[2] *= s;
return *this;
}
inline Point3 & operator /= ( const P3ScalarType s )
{
_v[0] /= s;
_v[1] /= s;
_v[2] /= s;
return *this;
}
// Norme
inline P3ScalarType Norm() const
{
return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] );
}
inline P3ScalarType SquaredNorm() const
{
return ( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] );
}
// Scalatura differenziata
inline Point3 & Scale( const P3ScalarType sx, const P3ScalarType sy, const P3ScalarType sz )
{
_v[0] *= sx;
_v[1] *= sy;
_v[2] *= sz;
return *this; return *this;
} }
inline Point3 & Scale( const Point3 & p ) inline Point3 & Scale( const Point3 & p )
{ {
_v[0] *= p._v[0]; data()[0] *= p.data()[0];
_v[1] *= p._v[1]; data()[1] *= p.data()[1];
_v[2] *= p._v[2]; data()[2] *= p.data()[2];
return *this;
}
// Normalizzazione
inline Point3 & Normalize()
{
P3ScalarType n = math::Sqrt(_v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2]);
if(n>0.0) { _v[0] /= n; _v[1] /= n; _v[2] /= n; }
return *this; return *this;
} }
@ -340,11 +173,11 @@ public:
* 0 and 180 degrees we opt for the elevation angle to obtain a more * 0 and 180 degrees we opt for the elevation angle to obtain a more
* intuitive spherical coordinate system. * intuitive spherical coordinate system.
*/ */
void ToPolar(P3ScalarType &ro, P3ScalarType &theta, P3ScalarType &phi) const void ToPolar(Scalar &ro, Scalar &theta, Scalar &phi) const
{ {
ro = Norm(); ro = this->norm();
theta = (P3ScalarType)atan2(_v[2], _v[0]); theta = (Scalar)atan2(data()[2], data()[0]);
phi = (P3ScalarType)asin(_v[1]/ro); phi = (Scalar)asin(data()[1]/ro);
} }
/** /**
@ -357,14 +190,14 @@ public:
* 0 and 180 degrees, we opt for the elevation angle to obtain a more * 0 and 180 degrees, we opt for the elevation angle to obtain a more
* intuitive spherical coordinate system. * intuitive spherical coordinate system.
*/ */
void FromPolar(const P3ScalarType &ro, const P3ScalarType &theta, const P3ScalarType &phi) void FromPolar(const Scalar &ro, const Scalar &theta, const Scalar &phi)
{ {
_v[0]= ro*cos(theta)*cos(phi); data()[0]= ro*cos(theta)*cos(phi);
_v[1]= ro*sin(phi); data()[1]= ro*sin(phi);
_v[2]= ro*sin(theta)*cos(phi); data()[2]= ro*sin(theta)*cos(phi);
} }
Box3<P3ScalarType> GetBBox(Box3<P3ScalarType> &bb) const; Box3<_Scalar> GetBBox(Box3<_Scalar> &bb) const;
//@} //@}
//@{ //@{
@ -372,113 +205,64 @@ public:
Note that the reverse z prioritized ordering, useful in many situations. Note that the reverse z prioritized ordering, useful in many situations.
**/ **/
inline bool operator == ( Point3 const & p ) const
{
return _v[0]==p._v[0] && _v[1]==p._v[1] && _v[2]==p._v[2];
}
inline bool operator != ( Point3 const & p ) const
{
return _v[0]!=p._v[0] || _v[1]!=p._v[1] || _v[2]!=p._v[2];
}
inline bool operator < ( Point3 const & p ) const inline bool operator < ( Point3 const & p ) const
{ {
return (_v[2]!=p._v[2])?(_v[2]<p._v[2]): return (data()[2]!=p.data()[2])?(data()[2]<p.data()[2]):
(_v[1]!=p._v[1])?(_v[1]<p._v[1]): (data()[1]!=p.data()[1])?(data()[1]<p.data()[1]):
(_v[0]<p._v[0]); (data()[0]<p.data()[0]);
} }
inline bool operator > ( Point3 const & p ) const inline bool operator > ( Point3 const & p ) const
{ {
return (_v[2]!=p._v[2])?(_v[2]>p._v[2]): return (data()[2]!=p.data()[2])?(data()[2]>p.data()[2]):
(_v[1]!=p._v[1])?(_v[1]>p._v[1]): (data()[1]!=p.data()[1])?(data()[1]>p.data()[1]):
(_v[0]>p._v[0]); (data()[0]>p.data()[0]);
} }
inline bool operator <= ( Point3 const & p ) const inline bool operator <= ( Point3 const & p ) const
{ {
return (_v[2]!=p._v[2])?(_v[2]< p._v[2]): return (data()[2]!=p.data()[2])?(data()[2]< p.data()[2]):
(_v[1]!=p._v[1])?(_v[1]< p._v[1]): (data()[1]!=p.data()[1])?(data()[1]< p.data()[1]):
(_v[0]<=p._v[0]); (data()[0]<=p.data()[0]);
} }
inline bool operator >= ( Point3 const & p ) const inline bool operator >= ( Point3 const & p ) const
{ {
return (_v[2]!=p._v[2])?(_v[2]> p._v[2]): return (data()[2]!=p.data()[2])?(data()[2]> p.data()[2]):
(_v[1]!=p._v[1])?(_v[1]> p._v[1]): (data()[1]!=p.data()[1])?(data()[1]> p.data()[1]):
(_v[0]>=p._v[0]); (data()[0]>=p.data()[0]);
}
inline Point3 operator - () const
{
return Point3<P3ScalarType> ( -_v[0], -_v[1], -_v[2] );
} }
//@} //@}
}; // end class definition }; // end class definition
template <class P3ScalarType>
inline P3ScalarType Angle( Point3<P3ScalarType> const & p1, Point3<P3ScalarType> const & p2 )
{
P3ScalarType w = p1.Norm()*p2.Norm();
if(w==0) return -1;
P3ScalarType t = (p1*p2)/w;
if(t>1) t = 1;
else if(t<-1) t = -1;
return (P3ScalarType) acos(t);
}
// versione uguale alla precedente ma che assume che i due vettori sono unitari // versione uguale alla precedente ma che assume che i due vettori sono unitari
template <class P3ScalarType> template <class Scalar>
inline P3ScalarType AngleN( Point3<P3ScalarType> const & p1, Point3<P3ScalarType> const & p2 ) inline Scalar AngleN( Point3<Scalar> const & p1, Point3<Scalar> const & p2 )
{ {
P3ScalarType w = p1*p2; Scalar w = p1*p2;
if(w>1) if(w>1)
w = 1; w = 1;
else if(w<-1) else if(w<-1)
w=-1; w=-1;
return (P3ScalarType) acos(w); return (Scalar) acos(w);
} }
template <class P3ScalarType> template <class Scalar>
inline P3ScalarType Norm( Point3<P3ScalarType> const & p ) inline Point3<Scalar> & Normalize( Point3<Scalar> & p )
{
return p.Norm();
}
template <class P3ScalarType>
inline P3ScalarType SquaredNorm( Point3<P3ScalarType> const & p )
{
return p.SquaredNorm();
}
template <class P3ScalarType>
inline Point3<P3ScalarType> & Normalize( Point3<P3ScalarType> & p )
{ {
p.Normalize(); p.Normalize();
return p; return p;
} }
template <class P3ScalarType>
inline P3ScalarType Distance( Point3<P3ScalarType> const & p1,Point3<P3ScalarType> const & p2 )
{
return (p1-p2).Norm();
}
template <class P3ScalarType>
inline P3ScalarType SquaredDistance( Point3<P3ScalarType> const & p1,Point3<P3ScalarType> const & p2 )
{
return (p1-p2).SquaredNorm();
}
// Dot product preciso numericamente (solo double!!) // Dot product preciso numericamente (solo double!!)
// Implementazione: si sommano i prodotti per ordine di esponente // Implementazione: si sommano i prodotti per ordine di esponente
// (prima le piu' grandi) // (prima le piu' grandi)
template<class P3ScalarType> template<class Scalar>
double stable_dot ( Point3<P3ScalarType> const & p0, Point3<P3ScalarType> const & p1 ) double stable_dot ( Point3<Scalar> const & p0, Point3<Scalar> const & p1 )
{ {
P3ScalarType k0 = p0._v[0]*p1._v[0]; Scalar k0 = p0.data()[0]*p1.data()[0];
P3ScalarType k1 = p0._v[1]*p1._v[1]; Scalar k1 = p0.data()[1]*p1.data()[1];
P3ScalarType k2 = p0._v[2]*p1._v[2]; Scalar k2 = p0.data()[2]*p1.data()[2];
int exp0,exp1,exp2; int exp0,exp1,exp2;
@ -505,14 +289,14 @@ double stable_dot ( Point3<P3ScalarType> const & p0, Point3<P3ScalarType> const
/// Point(p) Edge(v1-v2) dist, q is the point in v1-v2 with min dist /// Point(p) Edge(v1-v2) dist, q is the point in v1-v2 with min dist
template<class P3ScalarType> template<class Scalar>
P3ScalarType PSDist( const Point3<P3ScalarType> & p, Scalar PSDist( const Point3<Scalar> & p,
const Point3<P3ScalarType> & v1, const Point3<Scalar> & v1,
const Point3<P3ScalarType> & v2, const Point3<Scalar> & v2,
Point3<P3ScalarType> & q ) Point3<Scalar> & q )
{ {
Point3<P3ScalarType> e = v2-v1; Point3<Scalar> e = v2-v1;
P3ScalarType t = ((p-v1)*e)/e.SquaredNorm(); Scalar t = ((p-v1).dot(e))/e.SquaredNorm();
if(t<0) t = 0; if(t<0) t = 0;
else if(t>1) t = 1; else if(t>1) t = 1;
q = v1+e*t; q = v1+e*t;
@ -520,8 +304,8 @@ P3ScalarType PSDist( const Point3<P3ScalarType> & p,
} }
template <class P3ScalarType> template <class Scalar>
void GetUV( Point3<P3ScalarType> &n,Point3<P3ScalarType> &u, Point3<P3ScalarType> &v, Point3<P3ScalarType> up=(Point3<P3ScalarType>(0,1,0)) ) void GetUV( Point3<Scalar> &n,Point3<Scalar> &u, Point3<Scalar> &v, Point3<Scalar> up=(Point3<Scalar>(0,1,0)) )
{ {
n.Normalize(); n.Normalize();
const double LocEps=double(1e-7); const double LocEps=double(1e-7);
@ -530,18 +314,18 @@ void GetUV( Point3<P3ScalarType> &n,Point3<P3ScalarType> &u, Point3<P3ScalarType
if(len < LocEps) if(len < LocEps)
{ {
if(fabs(n[0])<fabs(n[1])){ if(fabs(n[0])<fabs(n[1])){
if(fabs(n[0])<fabs(n[2])) up=Point3<P3ScalarType>(1,0,0); // x is the min if(fabs(n[0])<fabs(n[2])) up=Point3<Scalar>(1,0,0); // x is the min
else up=Point3<P3ScalarType>(0,0,1); // z is the min else up=Point3<Scalar>(0,0,1); // z is the min
}else { }else {
if(fabs(n[1])<fabs(n[2])) up=Point3<P3ScalarType>(0,1,0); // y is the min if(fabs(n[1])<fabs(n[2])) up=Point3<Scalar>(0,1,0); // y is the min
else up=Point3<P3ScalarType>(0,0,1); // z is the min else up=Point3<Scalar>(0,0,1); // z is the min
} }
u=n^up; u=n^up;
} }
u.Normalize(); u.Normalize();
v=n^u; v=n^u;
v.Normalize(); v.Normalize();
Point3<P3ScalarType> uv=u^v; Point3<Scalar> uv=u^v;
} }
@ -566,3 +350,4 @@ typedef Point3<double> Point3d;
#endif #endif
#endif

View File

@ -20,48 +20,24 @@
* for more details. * * for more details. *
* * * *
****************************************************************************/ ****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $ #ifndef VCG_USE_EIGEN
Revision 1.12 2006/06/21 11:06:16 ganovelli #include "deprecated_point4.h"
changed return type of Zero() (to void) #else
Revision 1.11 2005/04/13 09:40:30 ponchio
Including math/bash.h
Revision 1.10 2005/03/18 16:34:42 fiorin
minor changes to comply gcc compiler
Revision 1.9 2005/01/21 18:02:11 ponchio
Removed dependence from matrix44 and changed VectProd
Revision 1.8 2005/01/12 11:25:02 ganovelli
added Dimension
Revision 1.7 2004/10/11 17:46:11 ganovelli
added definition of vector product (not implemented)
Revision 1.6 2004/05/10 11:16:19 ganovelli
include assert.h added
Revision 1.5 2004/03/31 10:09:58 cignoni
missing return value in zero()
Revision 1.4 2004/03/11 17:17:49 tarini
added commets (doxy), uniformed with new style, now using math::, ...
added HomoNormalize(), Zero()... remade StableDot() (hand made sort).
Revision 1.1 2004/02/10 01:11:28 cignoni
Edited Comments and GPL license
****************************************************************************/
#ifndef __VCGLIB_POINT4 #ifndef __VCGLIB_POINT4
#define __VCGLIB_POINT4 #define __VCGLIB_POINT4
#include <assert.h>
#include <vcg/math/base.h> #include "../math/eigen.h"
namespace vcg{
template<class Scalar> class Point4;
}
namespace Eigen{
template<typename Scalar>
struct ei_traits<vcg::Point4<Scalar> > : ei_traits<Eigen::Matrix<Scalar,4,1> > {};
}
namespace vcg { namespace vcg {
/** \addtogroup space */ /** \addtogroup space */
@ -72,224 +48,119 @@ namespace vcg {
All the usual operator (* + - ...) are defined. All the usual operator (* + - ...) are defined.
*/ */
template <class T> class Point4 template <class T> class Point4 : public Eigen::Matrix<T,4,1>
{ {
public: typedef Eigen::Matrix<T,4,1> _Base;
/// The only data member. Hidden to user. using _Base::coeff;
T _v[4]; using _Base::coeffRef;
using _Base::setZero;
using _Base::data;
using _Base::V;
public: public:
typedef T ScalarType;
_EIGEN_GENERIC_PUBLIC_INTERFACE(Point4,_Base);
typedef Scalar ScalarType;
VCG_EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Point4)
enum {Dimension = 4}; enum {Dimension = 4};
//@{ inline Point4() : Base() {}
inline Point4( const T nx, const T ny, const T nz , const T nw ) : Base(nx,ny,nz,nw) {}
inline Point4(const T p[4]) : Base(p) {}
inline Point4(const Point4& p) : Base(p) {}
template<typename OtherDerived>
inline Point4(const Eigen::MatrixBase<OtherDerived>& other) : Base(other) {}
/** @name Standard Constructors and Initializers
No casting operators have been introduced to avoid automatic unattended (and costly) conversion between different point types
**/
inline Point4 () { }
inline Point4 ( const T nx, const T ny, const T nz , const T nw )
{
_v[0] = nx; _v[1] = ny; _v[2] = nz; _v[3] = nw;
}
inline Point4 ( const T p[4] )
{
_v[0] = p[0]; _v[1]= p[1]; _v[2] = p[2]; _v[3]= p[3];
}
inline Point4 ( const Point4 & p )
{
_v[0]= p._v[0]; _v[1]= p._v[1]; _v[2]= p._v[2]; _v[3]= p._v[3];
}
inline void Zero()
{
_v[0] = _v[1] = _v[2] = _v[3]= 0;
}
template <class Q>
/// importer from different Point4 types /// importer from different Point4 types
inline void Import( const Point4<Q> & b ) template <class Q> inline void Import( const Point4<Q> & b ) { *this = b.template cast<T>(); }
{
_v[0] = T(b[0]); _v[1] = T(b[1]);
_v[2] = T(b[2]);
_v[3] = T(b[3]);
}
/// constuctor that imports from different Point4 types /// constuctor that imports from different Point4 types
template <class Q> template <class Q>
static inline Point4 Construct( const Point4<Q> & b ) static inline Point4 Construct( const Point4<Q> & b ) { return b.template cast<T>(); }
{
return Point4(T(b[0]),T(b[1]),T(b[2]),T(b[3]));
}
//@}
//@{ //@{
/** @name Data Access. inline T &X() {return Base::x();}
access to data is done by overloading of [] or explicit naming of coords (x,y,z,w) inline T &Y() {return Base::y();}
**/ inline T &Z() {return Base::z();}
inline const T & operator [] ( const int i ) const inline T &W() {return Base::w();}
{
assert(i>=0 && i<4);
return _v[i];
}
inline T & operator [] ( const int i )
{
assert(i>=0 && i<4);
return _v[i];
}
inline T &X() {return _v[0];}
inline T &Y() {return _v[1];}
inline T &Z() {return _v[2];}
inline T &W() {return _v[3];}
inline T const * V() const
{
return _v;
}
inline const T & V ( const int i ) const inline const T & V ( const int i ) const
{ {
assert(i>=0 && i<4); assert(i>=0 && i<4);
return _v[i]; return data()[i];
} }
inline T & V ( const int i ) inline T & V ( const int i )
{ {
assert(i>=0 && i<4); assert(i>=0 && i<4);
return _v[i]; 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 /// 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 inline T Ext( const int i ) const
{ {
if(i>=0 && i<=3) return _v[i]; if(i>=0 && i<=3) return data()[i];
else return 0; else return 0;
} }
//@} //@}
//@{
/** @name Linear operators and the likes
**/
inline Point4 operator + ( const Point4 & 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 Point4 & 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 T s ) const
{
return Point4( _v[0]*s, _v[1]*s, _v[2]*s, _v[3]*s );
}
inline Point4 operator / ( const T s ) const
{
return Point4( _v[0]/s, _v[1]/s, _v[2]/s, _v[3]/s );
}
inline Point4 & operator += ( const Point4 & 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 Point4 & 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 T s )
{
_v[0] *= s; _v[1] *= s; _v[2] *= s; _v[3] *= s;
return *this;
}
inline Point4 & operator /= ( const T s )
{
_v[0] /= s; _v[1] /= s; _v[2] /= s; _v[3] /= s;
return *this;
}
inline Point4 operator - () const
{
return Point4( -_v[0], -_v[1], -_v[2], -_v[3] );
}
inline Point4 VectProd ( const Point4 &x, const Point4 &z ) const inline Point4 VectProd ( const Point4 &x, const Point4 &z ) const
{ {
Point4 res; Point4 res;
const Point4 &y = *this; const Point4 &y = *this;
res[0] = y[1]*x[2]*z[3]-y[1]*x[3]*z[2]-x[1]*y[2]*z[3]+ res[0] = y[1]*x[2]*z[3]-y[1]*x[3]*z[2]-x[1]*y[2]*z[3]+
x[1]*y[3]*z[2]+z[1]*y[2]*x[3]-z[1]*y[3]*x[2]; x[1]*y[3]*z[2]+z[1]*y[2]*x[3]-z[1]*y[3]*x[2];
res[1] = y[0]*x[3]*z[2]-z[0]*y[2]*x[3]-y[0]*x[2]* res[1] = y[0]*x[3]*z[2]-z[0]*y[2]*x[3]-y[0]*x[2]*
z[3]+z[0]*y[3]*x[2]+x[0]*y[2]*z[3]-x[0]*y[3]*z[2]; z[3]+z[0]*y[3]*x[2]+x[0]*y[2]*z[3]-x[0]*y[3]*z[2];
res[2] = -y[0]*z[1]*x[3]+x[0]*z[1]*y[3]+y[0]*x[1]* res[2] = -y[0]*z[1]*x[3]+x[0]*z[1]*y[3]+y[0]*x[1]*
z[3]-x[0]*y[1]*z[3]-z[0]*x[1]*y[3]+z[0]*y[1]*x[3]; z[3]-x[0]*y[1]*z[3]-z[0]*x[1]*y[3]+z[0]*y[1]*x[3];
res[3] = -z[0]*y[1]*x[2]-y[0]*x[1]*z[2]+x[0]*y[1]* res[3] = -z[0]*y[1]*x[2]-y[0]*x[1]*z[2]+x[0]*y[1]*
z[2]+y[0]*z[1]*x[2]-x[0]*z[1]*y[2]+z[0]*x[1]*y[2]; z[2]+y[0]*z[1]*x[2]-x[0]*z[1]*y[2]+z[0]*x[1]*y[2];
return res; return res;
} }
//@}
//@{
/** @name Norms and normalizations
**/
/// Euclidian normal
inline T Norm() const
{
return math::Sqrt( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3] );
}
/// Squared euclidian normal
inline T SquaredNorm() const
{
return _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3];
}
/// Euclidian normalization
inline Point4 & Normalize()
{
T n = sqrt(_v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3] );
if(n>0.0) { _v[0] /= n; _v[1] /= n; _v[2] /= n; _v[3] /= n; }
return *this;
}
/// Homogeneous normalization (division by W) /// Homogeneous normalization (division by W)
inline Point4 & HomoNormalize(){ inline Point4 & HomoNormalize() {
if (_v[3]!=0.0) { _v[0] /= _v[3]; _v[1] /= _v[3]; _v[2] /= _v[3]; _v[3]=1.0; } if (data()[3]!=0.0) { Base::template start<3>() /= coeff(3); coeffRef(3) = 1.0; }
return *this; return *this;
}; }
//@}
//@{ //@{
/** @name Comparison operators (lexicographical order) /** @name Comparison operators (lexicographical order)
**/ **/
inline bool operator == ( const Point4& 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 != ( const Point4 & 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 < ( Point4 const & p ) const inline bool operator < ( Point4 const & p ) const
{ {
return (_v[3]!=p._v[3])?(_v[3]<p._v[3]): return (data()[3]!=p.data()[3])?(data()[3]<p.data()[3]):
(_v[2]!=p._v[2])?(_v[2]<p._v[2]): (data()[2]!=p.data()[2])?(data()[2]<p.data()[2]):
(_v[1]!=p._v[1])?(_v[1]<p._v[1]): (data()[1]!=p.data()[1])?(data()[1]<p.data()[1]):
(_v[0]<p._v[0]); (data()[0]<p.data()[0]);
} }
inline bool operator > ( const Point4 & p ) const inline bool operator > ( const Point4 & p ) const
{ {
return (_v[3]!=p._v[3])?(_v[3]>p._v[3]): return (data()[3]!=p.data()[3])?(data()[3]>p.data()[3]):
(_v[2]!=p._v[2])?(_v[2]>p._v[2]): (data()[2]!=p.data()[2])?(data()[2]>p.data()[2]):
(_v[1]!=p._v[1])?(_v[1]>p._v[1]): (data()[1]!=p.data()[1])?(data()[1]>p.data()[1]):
(_v[0]>p._v[0]); (data()[0]>p.data()[0]);
} }
inline bool operator <= ( const Point4 & p ) const inline bool operator <= ( const Point4 & p ) const
{ {
return (_v[3]!=p._v[3])?(_v[3]< p._v[3]): return (data()[3]!=p.data()[3])?(data()[3]< p.data()[3]):
(_v[2]!=p._v[2])?(_v[2]< p._v[2]): (data()[2]!=p.data()[2])?(data()[2]< p.data()[2]):
(_v[1]!=p._v[1])?(_v[1]< p._v[1]): (data()[1]!=p.data()[1])?(data()[1]< p.data()[1]):
(_v[0]<=p._v[0]); (data()[0]<=p.data()[0]);
} }
inline bool operator >= ( const Point4 & p ) const inline bool operator >= ( const Point4 & p ) const
{ {
return (_v[3]!=p._v[3])?(_v[3]> p._v[3]): return (data()[3]!=p.data()[3])?(data()[3]> p.data()[3]):
(_v[2]!=p._v[2])?(_v[2]> p._v[2]): (data()[2]!=p.data()[2])?(data()[2]> p.data()[2]):
(_v[1]!=p._v[1])?(_v[1]> p._v[1]): (data()[1]!=p.data()[1])?(data()[1]> p.data()[1]):
(_v[0]>=p._v[0]); (data()[0]>=p.data()[0]);
} }
//@} //@}
@ -297,22 +168,16 @@ public:
/** @name Dot products /** @name Dot products
**/ **/
// dot product
inline T operator * ( const Point4 & p ) const
{
return _v[0]*p._v[0] + _v[1]*p._v[1] + _v[2]*p._v[2] + _v[3]*p._v[3];
}
inline Point4 operator ^ ( const Point4& p ) const inline Point4 operator ^ ( const Point4& p ) const
{ {
assert(0);// not defined by two vectors (only put for metaprogramming) assert(0 && "not defined by two vectors (only put for metaprogramming)");
return Point4(); return Point4();
} }
/// slower version, more stable (double precision only) /// slower version, more stable (double precision only)
T StableDot ( const Point4<T> & p ) const T StableDot ( const Point4<T> & p ) const
{ {
T k0=data()[0]*p.data()[0], k1=data()[1]*p.data()[1], k2=data()[2]*p.data()[2], k3=data()[3]*p.data()[3];
T 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; int exp0,exp1,exp2,exp3;
frexp( double(k0), &exp0 );frexp( double(k1), &exp1 ); frexp( double(k0), &exp0 );frexp( double(k1), &exp1 );
@ -331,39 +196,6 @@ public:
}; // end class definition }; // end class definition
template <class T>
T Angle( const Point4<T>& p1, const Point4<T> & p2 )
{
T w = p1.Norm()*p2.Norm();
if(w==0) return -1;
T t = (p1*p2)/w;
if(t>1) t=1;
return T( math::Acos(t) );
}
template <class T>
inline T Norm( const Point4<T> & p )
{
return p.Norm();
}
template <class T>
inline T SquaredNorm( const Point4<T> & p )
{
return p.SquaredNorm();
}
template <class T>
inline T Distance( const Point4<T> & p1, const Point4<T> & p2 )
{
return Norm(p1-p2);
}
template <class T>
inline T SquaredDistance( const Point4<T> & p1, const Point4<T> & p2 )
{
return SquaredNorm(p1-p2);
}
/// slower version of dot product, more stable (double precision only) /// slower version of dot product, more stable (double precision only)
template<class T> template<class T>
@ -380,3 +212,5 @@ typedef Point4<double> Point4d;
/*@}*/ /*@}*/
} // end namespace } // end namespace
#endif #endif
#endif

View File

@ -112,8 +112,8 @@ public:
{ return _ori!=p._ori || _dir!=p._dir; } { return _ori!=p._ori || _dir!=p._dir; }
/// Projects a point on the ray /// Projects a point on the ray
inline ScalarType Projection( const PointType &p ) const inline ScalarType Projection( const PointType &p ) const
{ if (NORM) return ScalarType((p-_ori)*_dir); { if (NORM) return ScalarType((p-_ori).dot(_dir));
else return ScalarType((p-_ori)*_dir/_dir.SquaredNorm()); else return ScalarType((p-_ori).dot(_dir)/_dir.SquaredNorm());
} }
/// returns wheter this type is normalized or not /// returns wheter this type is normalized or not
static bool IsNormalized() {return NORM;}; static bool IsNormalized() {return NORM;};

View File

@ -72,40 +72,32 @@ namespace vcg {
inline void glMultMatrixE(const Matrix44f &matrix) { inline void glMultMatrixE(const Matrix44f &matrix) {
//glMultMatrixf((const GLfloat *)(matrix[0])); //glMultMatrixf((const GLfloat *)(matrix[0]));
if(glMultTransposeMatrixf) glMultTransposeMatrixf((const GLfloat *)(matrix[0])); if(glMultTransposeMatrixf) glMultTransposeMatrixf((const GLfloat *)(matrix.V()));
else { else {
Matrix44f tmp(matrix); glMultMatrixf((const GLfloat *)(matrix.transpose().eval().V()));
Transpose(tmp);
glMultMatrixf((const GLfloat *)(tmp[0]));
} }
} }
inline void glMultMatrix(const Matrix44f &matrix) { inline void glMultMatrix(const Matrix44f &matrix) {
Matrix44f tmp(matrix); glMultMatrixf((const GLfloat *)(matrix.transpose().eval().V()));
Transpose(tmp);
glMultMatrixf((const GLfloat *)(tmp[0]));
} }
inline void glMultMatrixE(const Matrix44d &matrix) { inline void glMultMatrixE(const Matrix44d &matrix) {
if(glMultTransposeMatrixd) glMultTransposeMatrixd((const GLdouble *)(matrix[0])); if(glMultTransposeMatrixd) glMultTransposeMatrixd((const GLdouble *)(matrix.V()));
else { else {
Matrix44d tmp(matrix); glMultMatrixd((const GLdouble *)(matrix.transpose().eval().V()));
Transpose(tmp);
glMultMatrixd((const GLdouble *)(tmp[0]));
} }
} }
inline void glMultMatrix(const Matrix44d &matrix) { inline void glMultMatrix(const Matrix44d &matrix) {
Matrix44d tmp(matrix); glMultMatrixd((const GLdouble *)(matrix.transpose().eval().V()));
Transpose(tmp);
glMultMatrixd((const GLdouble *)(tmp[0]));
} }
inline void glMultMatrixDirect(const Matrix44f &matrix) { inline void glMultMatrixDirect(const Matrix44f &matrix) {
glMultMatrixf((const GLfloat *)(matrix[0])); glMultMatrixf((const GLfloat *)(matrix.V()));
} }
inline void glMultMatrixDirect(const Matrix44d &matrix) { inline void glMultMatrixDirect(const Matrix44d &matrix) {
glMultMatrixd((const GLdouble *)(matrix[0])); glMultMatrixd((const GLdouble *)(matrix.V()));
} }
inline void glMultMatrix(const Similarityf &s) { inline void glMultMatrix(const Similarityf &s) {
@ -128,21 +120,23 @@ inline void glMultMatrix(const Similarityd &s) {
} }
inline void glGetv(const GLenum pname, Matrix44f & m){ inline void glGetv(const GLenum pname, Matrix44f & m){
glGetFloatv(pname,&m[0][0]); Matrix44f tmp;
Transpose(m); glGetFloatv(pname,tmp.V());
m = tmp.transpose();
} }
inline void glGetv(const GLenum pname, Matrix44d & m){ inline void glGetv(const GLenum pname, Matrix44d & m){
glGetDoublev(pname,&m[0][0]); Matrix44d tmp;
Transpose(m); glGetDoublev(pname,tmp.V());
m = tmp.transpose();
} }
inline void glGetDirectv(const GLenum pname, Matrix44f & m){ inline void glGetDirectv(const GLenum pname, Matrix44f & m){
glGetFloatv(pname,&m[0][0]); glGetFloatv(pname,m.V());
} }
inline void glGetDirecv(const GLenum pname, Matrix44d & m){ inline void glGetDirecv(const GLenum pname, Matrix44d & m){
glGetDoublev(pname,&m[0][0]); glGetDoublev(pname,m.V());
} }

View File

@ -243,9 +243,8 @@ inline void glBoxClip(const Box3<T> & b)
*(Point3<T>*)&m[2][0] = *(Point3<T>*)&v[0];m[2][3]=0; *(Point3<T>*)&m[2][0] = *(Point3<T>*)&v[0];m[2][3]=0;
*(Point3<T>*)&m[3][0] = *(Point3<T>*)&c1[0];m[3][3]=1; *(Point3<T>*)&m[3][0] = *(Point3<T>*)&c1[0];m[3][3]=1;
vcg::Transpose(m);
glPushMatrix(); glPushMatrix();
glMultMatrix(m); glMultMatrix(m.transpose());
glBegin(GL_QUADS); glBegin(GL_QUADS);
glNormal(Point3<T>(0,1,0)); glNormal(Point3<T>(0,1,0));
@ -279,5 +278,18 @@ template <class TetraType>
glTriangle3(Triangle3<typename TetraType::ScalarType>(c.P(1),c.P(0),c.P(3))); glTriangle3(Triangle3<typename TetraType::ScalarType>(c.P(1),c.P(0),c.P(3)));
} }
#ifdef VCG_USE_EIGEN
#define _WRAP_EIGEN_XPR(FUNC) template<typename Derived> \
inline void FUNC(const Eigen::MatrixBase<Derived>& p) { FUNC(p.eval()); }
_WRAP_EIGEN_XPR(glVertex)
_WRAP_EIGEN_XPR(glNormal)
_WRAP_EIGEN_XPR(glTexCoord)
_WRAP_EIGEN_XPR(glTranslate)
_WRAP_EIGEN_XPR(glScale)
#endif
}//namespace }//namespace
#endif #endif

View File

@ -486,8 +486,8 @@ int PathMode::Verse(Point3f reference_point,Point3f current_point,Point3f prev_p
prev_dir.Normalize(); prev_dir.Normalize();
next_dir.Normalize(); next_dir.Normalize();
float prev_coeff,next_coeff; float prev_coeff,next_coeff;
prev_coeff = prev_dir * reference_dir; prev_coeff = prev_dir.dot(reference_dir);
next_coeff = next_dir * reference_dir; next_coeff = next_dir.dot(reference_dir);
if (prev_coeff < 0.0f) if (prev_coeff < 0.0f)
prev_coeff = 0.0f; prev_coeff = 0.0f;
if (next_coeff < 0.0f) if (next_coeff < 0.0f)
@ -573,8 +573,8 @@ void AreaMode::Init(const std::vector < Point3f > &pts)
bool pts_not_in_line=false; bool pts_not_in_line=false;
Point3f a,b; Point3f a,b;
for(unsigned int i=0;i<onethird;i++){ for(unsigned int i=0;i<onethird;i++){
a=(pts[(i+ onethird )%npts] - pts[i%npts]).Normalize(); a=(pts[(i+ onethird )%npts] - pts[i%npts]).normalized();
b=(pts[(i+(2*onethird))%npts] - pts[i%npts]).Normalize(); b=(pts[(i+(2*onethird))%npts] - pts[i%npts]).normalized();
pts_not_in_line = (a ^ b).Norm() > EPSILON; pts_not_in_line = (a ^ b).Norm() > EPSILON;
if(pts_not_in_line){ if(pts_not_in_line){
plane.Init( pts[i%npts], plane.Init( pts[i%npts],

View File

@ -103,8 +103,8 @@ Plane3f GetViewPlane (const View < float >&camera, const Point3f & center)
Point3f vp = camera.ViewPoint (); Point3f vp = camera.ViewPoint ();
Plane3f pl; Plane3f pl;
Point3f plnorm = vp - center; Point3f plnorm = vp - center;
plnorm.Normalize (); plnorm.Normalize();
pl.Set (plnorm, plnorm * center); pl.Set(plnorm, plnorm.dot(center));
return pl; return pl;
} }
@ -331,16 +331,16 @@ Point3f HitSphere (Trackball * tb, const Point3f & p)
std::pair< float, bool > LineLineDistance(const Line3f & P,const Line3f & Q,Point3f & P_s, Point3f & Q_t){ std::pair< float, bool > LineLineDistance(const Line3f & P,const Line3f & Q,Point3f & P_s, Point3f & Q_t){
Point3f p0 = P.Origin (), Vp = P.Direction (); Point3f p0 = P.Origin (), Vp = P.Direction ();
Point3f q0 = Q.Origin (), Vq = Q.Direction (); Point3f q0 = Q.Origin (), Vq = Q.Direction ();
float VPVP = Vp * Vp; float VPVP = Vp.dot(Vp);
float VQVQ = Vq * Vq; float VQVQ = Vq.dot(Vq);
float VPVQ = Vp * Vq; float VPVQ = Vp.dot(Vq);
const float det = ( VPVP * VQVQ ) - ( VPVQ * VPVQ ); const float det = ( VPVP * VQVQ ) - ( VPVQ * VPVQ );
const float EPSILON = 0.00001f; const float EPSILON = 0.00001f;
if ( fabs(det) < EPSILON ) { if ( fabs(det) < EPSILON ) {
return std::make_pair(Distance(P,q0), true); return std::make_pair(Distance(P,q0), true);
} }
float b1= (q0 - p0) * Vp; float b1= (q0 - p0).dot(Vp);
float b2= (p0 - q0) * Vq; float b2= (p0 - q0).dot(Vq);
float s = ( (VQVQ * b1) + (VPVQ * b2) ) / det; float s = ( (VQVQ * b1) + (VPVQ * b2) ) / det;
float t = ( (VPVQ * b1) + (VPVP * b2) ) / det; float t = ( (VPVQ * b1) + (VPVP * b2) ) / det;
P_s = p0 + (Vp * s); P_s = p0 + (Vp * s);
@ -367,16 +367,16 @@ std::pair< float, bool > LineLineDistance(const Line3f & P,const Line3f & Q,Poin
std::pair< float, bool > RayLineDistance(const Ray3f & R,const Line3f & Q,Point3f & R_s, Point3f & Q_t){ std::pair< float, bool > RayLineDistance(const Ray3f & R,const Line3f & Q,Point3f & R_s, Point3f & Q_t){
Point3f r0 = R.Origin (), Vr = R.Direction (); Point3f r0 = R.Origin (), Vr = R.Direction ();
Point3f q0 = Q.Origin (), Vq = Q.Direction (); Point3f q0 = Q.Origin (), Vq = Q.Direction ();
float VRVR = Vr * Vr; float VRVR = Vr.dot(Vr);
float VQVQ = Vq * Vq; float VQVQ = Vq.dot(Vq);
float VRVQ = Vr * Vq; float VRVQ = Vr.dot(Vq);
const float det = ( VRVR * VQVQ ) - ( VRVQ * VRVQ ); const float det = ( VRVR * VQVQ ) - ( VRVQ * VRVQ );
const float EPSILON = 0.00001f; const float EPSILON = 0.00001f;
if ( ( det >= 0.0f ? det : -det) < EPSILON ) { if ( ( det >= 0.0f ? det : -det) < EPSILON ) {
return std::make_pair(Distance(Q,r0), true); return std::make_pair(Distance(Q,r0), true);
} }
float b1= (q0 - r0) * Vr; float b1= (q0 - r0).dot(Vr);
float b2= (r0 - q0) * Vq; float b2= (r0 - q0).dot(Vq);
float s = ( (VQVQ * b1) + (VRVQ * b2) ) / det; float s = ( (VQVQ * b1) + (VRVQ * b2) ) / det;
float t = ( (VRVQ * b1) + (VRVR * b2) ) / det; float t = ( (VRVQ * b1) + (VRVR * b2) ) / det;
if(s<0){ if(s<0){
@ -418,17 +418,17 @@ std::pair< float, bool > SegmentSegmentDistance(const Segment3f & R, const Segme
R_s=ClosestPoint(R,Q_t); R_s=ClosestPoint(R,Q_t);
return std::make_pair(Distance(R_s,Q_t),true); return std::make_pair(Distance(R_s,Q_t),true);
} }
Point3f r0 = R.P0(), Vr = (R.P1()-R.P0()).Normalize(); Point3f r0 = R.P0(), Vr = (R.P1()-R.P0()).normalized();
Point3f q0 = Q.P0(), Vq = (Q.P1()-Q.P0()).Normalize(); Point3f q0 = Q.P0(), Vq = (Q.P1()-Q.P0()).normalized();
float VRVR = Vr * Vr; float VRVR = Vr.dot(Vr);
float VQVQ = Vq * Vq; float VQVQ = Vq.dot(Vq);
float VRVQ = Vr * Vq; float VRVQ = Vr.dot(Vq);
const float det = ( VRVR * VQVQ ) - ( VRVQ * VRVQ ); const float det = ( VRVR * VQVQ ) - ( VRVQ * VRVQ );
const float EPSILON = 0.00001f; const float EPSILON = 0.00001f;
if ( ( det >= 0.0f ? det : -det) < EPSILON ) { if ( ( det >= 0.0f ? det : -det) < EPSILON ) {
Line3f lR(R.P0(),R.P1()); Line3f lR(R.P0(),R.P1());
float qa=lR.Projection(Q.P0()); float qa=lR.Projection(Q.P0());
float qb=lR.Projection(Q.P1()); float qb=lR.Projection(Q.P1());
if( (qa<=0.0f) && qb<=(0.0f)){ if( (qa<=0.0f) && qb<=(0.0f)){
R_s=R.P0(); R_s=R.P0();
Q_t=ClosestPoint(Q,R_s); Q_t=ClosestPoint(Q,R_s);
@ -453,8 +453,8 @@ std::pair< float, bool > SegmentSegmentDistance(const Segment3f & R, const Segme
} }
return std::make_pair(Distance(R_s,Q_t),true); return std::make_pair(Distance(R_s,Q_t),true);
} }
float b1= (q0 - r0) * Vr; float b1= (q0 - r0).dot(Vr);
float b2= (r0 - q0) * Vq; float b2= (r0 - q0).dot(Vq);
float s = ( (VQVQ * b1) + (VRVQ * b2) ) / det; float s = ( (VQVQ * b1) + (VRVQ * b2) ) / det;
float t = ( (VRVQ * b1) + (VRVR * b2) ) / det; float t = ( (VRVQ * b1) + (VRVR * b2) ) / det;
if( s < 0 ){ if( s < 0 ){
@ -529,7 +529,7 @@ Line3f ProjectLineOnPlane(const Line3f & ln, const Plane3f & pl)
*/ */
float signedDistance(Line3f line,Point3f pt,Point3f positive_dir) float signedDistance(Line3f line,Point3f pt,Point3f positive_dir)
{ {
return Distance(line,pt) * ((((pt-ClosestPoint(line,pt)) * positive_dir) >= 0.0f )? 1.0f: -1.0f); return Distance(line,pt) * ((((pt-ClosestPoint(line,pt)).dot(positive_dir)) >= 0.0f )? 1.0f: -1.0f);
} }
/*! /*!
@ -557,10 +557,10 @@ template<class T>
inline bool IntersectionRayPlane( const Plane3<T> & pl, const Ray3<T> & ray, Point3<T> &po){ inline bool IntersectionRayPlane( const Plane3<T> & pl, const Ray3<T> & ray, Point3<T> &po){
const T epsilon = T(1e-8); const T epsilon = T(1e-8);
T k = pl.Direction() * ray.Direction(); // Compute 'k' factor T k = pl.Direction().dot(ray.Direction()); // Compute 'k' factor
if( (k > -epsilon) && (k < epsilon)) if( (k > -epsilon) && (k < epsilon))
return false; return false;
T r = (pl.Offset() - pl.Direction()*ray.Origin())/k; // Compute ray distance T r = (pl.Offset() - pl.Direction().dot(ray.Origin()))/k; // Compute ray distance
if (r < 0) if (r < 0)
return false; return false;
po = ray.Origin() + ray.Direction()*r; po = ray.Origin() + ray.Direction()*r;
@ -887,8 +887,8 @@ void DrawUglyPlaneMode(Trackball * tb,Plane3f plane)
if(norm == d1 || norm == -d1) if(norm == d1 || norm == -d1)
d1 = Point3f(1,0,0); d1 = Point3f(1,0,0);
d2=plane.Projection(d1); d2=plane.Projection(d1);
d1=(d2 - p0).Normalize(); d1=(d2 - p0).normalized();
d2=(d1 ^ norm).Normalize(); d2=(d1 ^ norm).normalized();
glLineWidth(3.0); glLineWidth(3.0);
glColor3f(0.2f, 0.2f, 0.9f); glColor3f(0.2f, 0.2f, 0.9f);
glBegin(GL_LINES); glBegin(GL_LINES);
@ -945,8 +945,8 @@ void DrawUglyCylinderMode(Trackball * tb,Line3f axis)
if(norm == d1 || norm == -d1) if(norm == d1 || norm == -d1)
d1 = Point3f(1,0,0); d1 = Point3f(1,0,0);
d2=plane.Projection(d1); d2=plane.Projection(d1);
d1=(d2 - p0).Normalize(); d1=(d2 - p0).normalized();
d2=(d1 ^ norm).Normalize(); d2=(d1 ^ norm).normalized();
glLineWidth(1.0); glLineWidth(1.0);
glColor3f(0.2f, 0.2f, 0.9f); glColor3f(0.2f, 0.2f, 0.9f);
for(int i=-100;i<100;i++){ for(int i=-100;i<100;i++){
@ -1098,8 +1098,8 @@ void DrawUglyAreaMode(Trackball * tb,const std::vector < Point3f > &points,
if(norm == d1 || norm == -d1) if(norm == d1 || norm == -d1)
d1 = Point3f(1,0,0); d1 = Point3f(1,0,0);
d2=plane.Projection(d1); d2=plane.Projection(d1);
d1=(d2 - p0).Normalize(); d1=(d2 - p0).normalized();
d2=(d1 ^ norm).Normalize(); d2=(d1 ^ norm).normalized();
glLineWidth(3.0); glLineWidth(3.0);
glColor3f(0.2f, 0.2f, 0.9f); glColor3f(0.2f, 0.2f, 0.9f);
glBegin(GL_LINES); glBegin(GL_LINES);

View File

@ -151,10 +151,10 @@ template <class T> void View<T>::GetView() {
glGetDoublev(GL_PROJECTION_MATRIX, m); glGetDoublev(GL_PROJECTION_MATRIX, m);
proj.Import(Matrix44d(m)); proj.Import(Matrix44d(m));
Transpose(proj); proj = proj.transpose().eval();
glGetDoublev(GL_MODELVIEW_MATRIX, m); glGetDoublev(GL_MODELVIEW_MATRIX, m);
model.Import(Matrix44d(m)); model.Import(Matrix44d(m));
Transpose(model); model = model.transpose().eval();
glGetIntegerv(GL_VIEWPORT, (GLint*)viewport); glGetIntegerv(GL_VIEWPORT, (GLint*)viewport);
@ -205,14 +205,14 @@ template <class T> Line3<T> View<T>::ViewLineFromWindow(const Point3<T> &p)
template <class T> Point3<T> View<T>::Project(const Point3<T> &p) const { template <class T> Point3<T> View<T>::Project(const Point3<T> &p) const {
Point3<T> r; Point3<T> r;
r = matrix * p; r = matrix * p;
return NormDevCoordToWindowCoord(r); return NormDevCoordToWindowCoord(r);
} }
template <class T> Point3<T> View<T>::UnProject(const Point3<T> &p) const { template <class T> Point3<T> View<T>::UnProject(const Point3<T> &p) const {
Point3<T> s = WindowCoordToNormDevCoord(p); Point3<T> s = WindowCoordToNormDevCoord(p);
s = inverse * s ; s = inverse * s ;
return s; return s;
} }
// Come spiegato nelle glspec // Come spiegato nelle glspec

View File

@ -230,7 +230,7 @@ namespace io {
else return false; else return false;
// PTX transformation matrix is transposed // PTX transformation matrix is transposed
Transpose(currtrasf); currtrasf = currtrasf.transpose().eval();
// allocating vertex space // allocating vertex space
int vn = rownum*colnum; int vn = rownum*colnum;