fix transform * matrix products: in particular it now truely considers the rhs as a set of (homogeneous) points and do not neglect the homogeneous coordinates in the case of affine transform

This commit is contained in:
Gael Guennebaud 2011-03-02 19:26:38 +01:00
parent adacacb285
commit d30f0c0953

View File

@ -43,7 +43,9 @@ struct transform_traits
template< typename TransformType, template< typename TransformType,
typename MatrixType, typename MatrixType,
bool IsProjective = transform_traits<TransformType>::IsProjective> int Case = transform_traits<TransformType>::IsProjective ? 0
: int(MatrixType::RowsAtCompileTime) == int(transform_traits<TransformType>::HDim) ? 1
: 2>
struct transform_right_product_impl; struct transform_right_product_impl;
template< typename Other, template< typename Other,
@ -1204,7 +1206,7 @@ struct transform_product_result
}; };
template< typename TransformType, typename MatrixType > template< typename TransformType, typename MatrixType >
struct transform_right_product_impl< TransformType, MatrixType, true > struct transform_right_product_impl< TransformType, MatrixType, 0 >
{ {
typedef typename MatrixType::PlainObject ResultType; typedef typename MatrixType::PlainObject ResultType;
@ -1215,7 +1217,7 @@ struct transform_right_product_impl< TransformType, MatrixType, true >
}; };
template< typename TransformType, typename MatrixType > template< typename TransformType, typename MatrixType >
struct transform_right_product_impl< TransformType, MatrixType, false > struct transform_right_product_impl< TransformType, MatrixType, 1 >
{ {
enum { enum {
Dim = TransformType::Dim, Dim = TransformType::Dim,
@ -1228,20 +1230,39 @@ struct transform_right_product_impl< TransformType, MatrixType, false >
EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other) EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other)
{ {
EIGEN_STATIC_ASSERT(OtherRows==Dim || OtherRows==HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES); EIGEN_STATIC_ASSERT(OtherRows==HDim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
typedef Block<ResultType, Dim, OtherCols> TopLeftLhs; typedef Block<ResultType, Dim, OtherCols> TopLeftLhs;
typedef Block<const MatrixType, Dim, OtherCols> TopLeftRhs;
ResultType res(other.rows(),other.cols()); ResultType res(other.rows(),other.cols());
TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.affine() * other;
res.row(OtherRows-1) = other.row(OtherRows-1);
TopLeftLhs(res, 0, 0, Dim, other.cols()) = return res;
( T.linear() * TopLeftRhs(other, 0, 0, Dim, other.cols()) ).colwise() + }
T.translation(); };
// we need to take .rows() because OtherRows might be Dim or HDim template< typename TransformType, typename MatrixType >
if (OtherRows==HDim) struct transform_right_product_impl< TransformType, MatrixType, 2 >
res.row(other.rows()) = other.row(other.rows()); {
enum {
Dim = TransformType::Dim,
HDim = TransformType::HDim,
OtherRows = MatrixType::RowsAtCompileTime,
OtherCols = MatrixType::ColsAtCompileTime
};
typedef typename MatrixType::PlainObject ResultType;
EIGEN_STRONG_INLINE static ResultType run(const TransformType& T, const MatrixType& other)
{
EIGEN_STATIC_ASSERT(OtherRows==Dim, YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
typedef Block<ResultType, Dim, OtherCols> TopLeftLhs;
ResultType res(other.rows(),other.cols());
TopLeftLhs(res, 0, 0, Dim, other.cols()).noalias() = T.linear() * other;
TopLeftLhs(res, 0, 0, Dim, other.cols()).colwise() += T.translation();
return res; return res;
} }