mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
* 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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user