* added a pseudo expression Array giving access to:

- matrix-scalar addition/subtraction operators, e.g.:
       m.array() += 0.5;
   - matrix/matrix comparison operators, e.g.:
      if (m1.array() < m2.array()) {}
* fix compilation issues with Transform and gcc < 4.1
This commit is contained in:
Gael Guennebaud
2008-06-20 12:38:03 +00:00
parent e735692e37
commit 54238961d6
8 changed files with 255 additions and 57 deletions

View File

@@ -25,6 +25,16 @@
#ifndef EIGEN_TRANSFORM_H
#define EIGEN_TRANSFORM_H
// Note that we have to pass Dim and HDim because it is not allowed to use a template
// parameter to define a template specialization. To be more precise, in the following
// specializations, it is not allowed to use Dim+1 instead of HDim.
template< typename Other,
int Dim,
int HDim,
int OtherRows=Other::RowsAtCompileTime,
int OtherCols=Other::ColsAtCompileTime>
struct ei_transform_product_impl;
/** \class Transform
*
* \brief Represents an homogeneous transformation in a N dimensional space
@@ -57,52 +67,6 @@ protected:
MatrixType m_matrix;
template<typename Other,
int OtherRows=Other::RowsAtCompileTime,
int OtherCols=Other::ColsAtCompileTime>
struct ei_transform_product_impl;
// FIXME these specializations of ei_transform_product_impl does not work with gcc 3.3 and 3.4 because
// Dim depends on a template parameter. Replacing Dim by 3 (for the 3D case) works.
// note that these specializations have to be defined here,
// otherwise some compilers (at least ICC and NVCC) complain about
// the use of Dim in the specialization parameters.
template<typename Other>
struct ei_transform_product_impl<Other,Dim+1,Dim+1>
{
typedef typename Transform<Scalar,Dim>::MatrixType MatrixType;
typedef typename ProductReturnType<MatrixType,Other>::Type ResultType;
static ResultType run(const Transform<Scalar,Dim>& tr, const Other& other)
{ return tr.matrix() * other; }
};
template<typename Other>
struct ei_transform_product_impl<Other,Dim+1,1>
{
typedef typename Transform<Scalar,Dim>::MatrixType MatrixType;
typedef typename ProductReturnType<MatrixType,Other>::Type ResultType;
static ResultType run(const Transform<Scalar,Dim>& tr, const Other& other)
{ return tr.matrix() * other; }
};
template<typename Other>
struct ei_transform_product_impl<Other,Dim,1>
{
typedef typename Transform<Scalar,Dim>::AffineMatrixRef MatrixType;
typedef const CwiseUnaryOp<
ei_scalar_multiple_op<Scalar>,
NestByValue<CwiseBinaryOp<
ei_scalar_sum_op<Scalar>,
NestByValue<typename ProductReturnType<NestByValue<MatrixType>,Other>::Type >,
NestByValue<typename Transform<Scalar,Dim>::VectorRef> > >
> ResultType;
// FIXME shall we offer an optimized version when the last row is know to be 0,0...,0,1 ?
static ResultType run(const Transform<Scalar,Dim>& tr, const Other& other)
{ return ((tr.affine().nestByValue() * other).nestByValue() + tr.translation().nestByValue()).nestByValue()
* (Scalar(1) / ( (tr.matrix().template block<1,Dim>(Dim,0) * other).coeff(0) + tr.matrix().coeff(Dim,Dim))); }
};
public:
/** Default constructor without initialization of the coefficients. */
@@ -144,7 +108,7 @@ public:
inline VectorRef translation() { return m_matrix.template block<Dim,1>(0,Dim); }
template<typename OtherDerived>
const typename ei_transform_product_impl<OtherDerived>::ResultType
const typename ei_transform_product_impl<OtherDerived,_Dim,_Dim+1>::ResultType
operator * (const MatrixBase<OtherDerived> &other) const;
/** Contatenates two transformations */
@@ -225,12 +189,17 @@ QMatrix Transform<Scalar,Dim>::toQMatrix(void) const
}
#endif
/** \returns an expression of the product between the transform \c *this and a matrix expression \a other
*
* The right hand side \a other might be a vector of size Dim, an homogeneous vector of size Dim+1
* or a transformation matrix of size Dim+1 x Dim+1.
*/
template<typename Scalar, int Dim>
template<typename OtherDerived>
const typename Transform<Scalar,Dim>::template ei_transform_product_impl<OtherDerived>::ResultType
const typename ei_transform_product_impl<OtherDerived,Dim,Dim+1>::ResultType
Transform<Scalar,Dim>::operator*(const MatrixBase<OtherDerived> &other) const
{
return ei_transform_product_impl<OtherDerived>::run(*this,other.derived());
return ei_transform_product_impl<OtherDerived,Dim,HDim>::run(*this,other.derived());
}
/** Applies on the right the non uniform scale transformation represented
@@ -408,4 +377,47 @@ Transform<Scalar,Dim>::fromPositionOrientationScale(const MatrixBase<PositionDer
return *this;
}
/***********************************
*** Specializations of operator* ***
***********************************/
template<typename Other, int Dim, int HDim>
struct ei_transform_product_impl<Other,Dim,HDim, HDim,HDim>
{
typedef Transform<typename Other::Scalar,Dim> Transform;
typedef typename Transform::MatrixType MatrixType;
typedef typename ProductReturnType<MatrixType,Other>::Type ResultType;
static ResultType run(const Transform& tr, const Other& other)
{ return tr.matrix() * other; }
};
template<typename Other, int Dim, int HDim>
struct ei_transform_product_impl<Other,Dim,HDim, HDim,1>
{
typedef Transform<typename Other::Scalar,Dim> Transform;
typedef typename Transform::MatrixType MatrixType;
typedef typename ProductReturnType<MatrixType,Other>::Type ResultType;
static ResultType run(const Transform& tr, const Other& other)
{ return tr.matrix() * other; }
};
template<typename Other, int Dim, int HDim>
struct ei_transform_product_impl<Other,Dim,HDim, Dim,1>
{
typedef typename Other::Scalar Scalar;
typedef Transform<Scalar,Dim> Transform;
typedef typename Transform::AffineMatrixRef MatrixType;
typedef const CwiseUnaryOp<
ei_scalar_multiple_op<Scalar>,
NestByValue<CwiseBinaryOp<
ei_scalar_sum_op<Scalar>,
NestByValue<typename ProductReturnType<NestByValue<MatrixType>,Other>::Type >,
NestByValue<typename Transform::VectorRef> > >
> ResultType;
// FIXME shall we offer an optimized version when the last row is known to be 0,0...,0,1 ?
static ResultType run(const Transform& tr, const Other& other)
{ return ((tr.affine().nestByValue() * other).nestByValue() + tr.translation().nestByValue()).nestByValue()
* (Scalar(1) / ( (tr.matrix().template block<1,Dim>(Dim,0) * other).coeff(0) + tr.matrix().coeff(Dim,Dim))); }
};
#endif // EIGEN_TRANSFORM_H