Big change in DiagonalMatrix and Geometry/Scaling:

* previous DiagonalMatrix expression is now DiagonalMatrixWrapper
* DiagonalMatrix class is now for storage
* add the DiagonalMatrixBase class to factorize code of the
  two previous classes
* remove Scaling class (it is now a global function)
* add UniformScaling helper class
  (don't use it directly, use the Scaling function)
* add the Scaling global function to simplify the creation
  of scaling objects
There is still a lot to do, in particular about DiagonalProduct for which
the goal is to get rid of the "if()" in the coeff() function. At least
it is not worse than before ! Also need to uptade the tutorial and add more doc.
This commit is contained in:
Gael Guennebaud
2009-01-28 16:26:06 +00:00
parent da555585e2
commit 1b194193ef
13 changed files with 439 additions and 237 deletions

View File

@@ -193,8 +193,7 @@ public:
Quaternion slerp(Scalar t, const Quaternion& other) const;
template<typename Derived>
Vector3 operator* (const MatrixBase<Derived>& vec) const;
Vector3 operator* (const Vector3& vec) const;
/** \returns \c *this with scalar type casted to \a NewScalarType
*
@@ -256,17 +255,15 @@ inline Quaternion<Scalar>& Quaternion<Scalar>::operator*= (const Quaternion& oth
* - Via a Matrix3: 24 + 15n
*/
template <typename Scalar>
template<typename Derived>
inline typename Quaternion<Scalar>::Vector3
Quaternion<Scalar>::operator* (const MatrixBase<Derived>& v) const
Quaternion<Scalar>::operator* (const Vector3& v) const
{
// Note that this algorithm comes from the optimization by hand
// of the conversion to a Matrix followed by a Matrix/Vector product.
// It appears to be much faster than the common algorithm found
// in the litterature (30 versus 39 flops). It also requires two
// Vector3 as temporaries.
Vector3 uv;
uv = 2 * this->vec().cross(v);
Vector3 uv = Scalar(2) * this->vec().cross(v);
return v + this->w() * uv + this->vec().cross(uv);
}

View File

@@ -59,9 +59,19 @@ class RotationBase
inline Transform<Scalar,Dim> operator*(const Translation<Scalar,Dim>& t) const
{ return toRotationMatrix() * t; }
/** \returns the concatenation of the rotation \c *this with a scaling \a s */
inline RotationMatrixType operator*(const Scaling<Scalar,Dim>& s) const
{ return toRotationMatrix() * s; }
/** \returns the concatenation of the rotation \c *this with a uniform scaling \a s */
inline RotationMatrixType operator*(const UniformScaling<Scalar>& s) const
{ return toRotationMatrix() * s.factor(); }
/** \returns the concatenation of the rotation \c *this with a linear transformation \a l */
template<typename OtherDerived>
inline RotationMatrixType operator*(const MatrixBase<OtherDerived>& l) const
{ return toRotationMatrix() * l.derived(); }
/** \returns the concatenation of a linear transformation \a l with the rotation \a r */
template<typename OtherDerived> friend
inline RotationMatrixType operator*(const MatrixBase<OtherDerived>& l, const Derived& r)
{ return l.derived() * r.toRotationMatrix(); }
/** \returns the concatenation of the rotation \c *this with an affine transformation \a t */
inline Transform<Scalar,Dim> operator*(const Transform<Scalar,Dim>& t) const

View File

@@ -29,102 +29,72 @@
*
* \class Scaling
*
* \brief Represents a possibly non uniform scaling transformation
* \brief Represents a generic uniform scaling transformation
*
* \param _Scalar the scalar type, i.e., the type of the coefficients.
* \param _Dim the dimension of the space, can be a compile time value or Dynamic
*
* \note This class is not aimed to be used to store a scaling transformation,
* This class represent a uniform scaling transformation. It is the return
* type of Scaling(Scalar), and most of the time this is the only way it
* is used. In particular, this class is not aimed to be used to store a scaling transformation,
* but rather to make easier the constructions and updates of Transform objects.
*
* \sa class Translation, class Transform
* To represent an axis aligned scaling, use the DiagonalMatrix class.
*
* \sa Scaling(), class DiagonalMatrix, MatrixBase::asDiagonal(), class Translation, class Transform
*/
template<typename _Scalar, int _Dim>
class Scaling
template<typename _Scalar>
class UniformScaling
{
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim)
/** dimension of the space */
enum { Dim = _Dim };
/** the scalar type of the coefficients */
typedef _Scalar Scalar;
/** corresponding vector type */
typedef Matrix<Scalar,Dim,1> VectorType;
/** corresponding linear transformation matrix type */
typedef Matrix<Scalar,Dim,Dim> LinearMatrixType;
/** corresponding translation type */
typedef Translation<Scalar,Dim> TranslationType;
/** corresponding affine transformation type */
typedef Transform<Scalar,Dim> TransformType;
protected:
VectorType m_coeffs;
Scalar m_factor;
public:
/** Default constructor without initialization. */
Scaling() {}
UniformScaling() {}
/** Constructs and initialize a uniform scaling transformation */
explicit inline Scaling(const Scalar& s) { m_coeffs.setConstant(s); }
/** 2D only */
inline Scaling(const Scalar& sx, const Scalar& sy)
{
ei_assert(Dim==2);
m_coeffs.x() = sx;
m_coeffs.y() = sy;
}
/** 3D only */
inline Scaling(const Scalar& sx, const Scalar& sy, const Scalar& sz)
{
ei_assert(Dim==3);
m_coeffs.x() = sx;
m_coeffs.y() = sy;
m_coeffs.z() = sz;
}
/** Constructs and initialize the scaling transformation from a vector of scaling coefficients */
explicit inline Scaling(const VectorType& coeffs) : m_coeffs(coeffs) {}
explicit inline UniformScaling(const Scalar& s) : m_factor(s) {}
const VectorType& coeffs() const { return m_coeffs; }
VectorType& coeffs() { return m_coeffs; }
const Scalar& factor() const { return m_factor; }
Scalar& factor() { return m_factor; }
/** Concatenates two scaling */
inline Scaling operator* (const Scaling& other) const
{ return Scaling(coeffs().cwise() * other.coeffs()); }
/** Concatenates two uniform scaling */
inline UniformScaling operator* (const UniformScaling& other) const
{ return UniformScaling(m_factor * other.factor()); }
/** Concatenates a scaling and a translation */
inline TransformType operator* (const TranslationType& t) const;
/** Concatenates a uniform scaling and a translation */
template<int Dim>
inline Transform<Scalar,Dim> operator* (const Translation<Scalar,Dim>& t) const;
/** Concatenates a scaling and an affine transformation */
inline TransformType operator* (const TransformType& t) const;
/** Concatenates a uniform scaling and an affine transformation */
template<int Dim>
inline Transform<Scalar,Dim> operator* (const Transform<Scalar,Dim>& t) const;
/** Concatenates a scaling and a linear transformation matrix */
/** Concatenates a uniform scaling and a linear transformation matrix */
// TODO returns an expression
inline LinearMatrixType operator* (const LinearMatrixType& other) const
{ return coeffs().asDiagonal() * other; }
/** Concatenates a linear transformation matrix and a scaling */
// TODO returns an expression
friend inline LinearMatrixType operator* (const LinearMatrixType& other, const Scaling& s)
{ return other * s.coeffs().asDiagonal(); }
template<typename Derived>
inline LinearMatrixType operator*(const RotationBase<Derived,Dim>& r) const
{ return *this * r.toRotationMatrix(); }
inline typename ei_eval<Derived>::type operator* (const MatrixBase<Derived>& other) const
{ return other * m_factor; }
/** Applies scaling to vector */
inline VectorType operator* (const VectorType& other) const
{ return coeffs().asDiagonal() * other; }
/** Concatenates a linear transformation matrix and a uniform scaling */
// TODO returns an expression
template<typename Derived>
friend inline typename ei_eval<Derived>::type
operator* (const MatrixBase<Derived>& other, const UniformScaling& s)
{ return other * s.factor(); }
template<typename Derived,int Dim>
inline Matrix<Scalar,Dim,Dim> operator*(const RotationBase<Derived,Dim>& r) const
{ return r.toRotationMatrix() * m_factor; }
/** \returns the inverse scaling */
inline Scaling inverse() const
{ return Scaling(coeffs().cwise().inverse()); }
inline Scaling& operator=(const Scaling& other)
{
m_coeffs = other.m_coeffs;
return *this;
}
inline UniformScaling inverse() const
{ return UniformScaling(Scalar(1)/m_factor); }
/** \returns \c *this with scalar type casted to \a NewScalarType
*
@@ -132,50 +102,58 @@ public:
* then this function smartly returns a const reference to \c *this.
*/
template<typename NewScalarType>
inline typename ei_cast_return_type<Scaling,Scaling<NewScalarType,Dim> >::type cast() const
{ return typename ei_cast_return_type<Scaling,Scaling<NewScalarType,Dim> >::type(*this); }
inline UniformScaling<NewScalarType> cast() const
{ return UniformScaling<NewScalarType>(NewScalarType(m_factor)); }
/** Copy constructor with scalar type conversion */
template<typename OtherScalarType>
inline explicit Scaling(const Scaling<OtherScalarType,Dim>& other)
{ m_coeffs = other.coeffs().template cast<Scalar>(); }
inline explicit UniformScaling(const UniformScaling<OtherScalarType>& other)
{ m_factor = Scalar(other.factor()); }
/** \returns \c true if \c *this is approximately equal to \a other, within the precision
* determined by \a prec.
*
* \sa MatrixBase::isApprox() */
bool isApprox(const Scaling& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
{ return m_coeffs.isApprox(other.m_coeffs, prec); }
bool isApprox(const UniformScaling& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
{ return ei_isApprox(m_factor, other.factor(), prec); }
};
/** Constructs a uniform scaling from scale factor \a s */
UniformScaling<float> Scaling(float s) { return UniformScaling<float>(s); }
/** Constructs a uniform scaling from scale factor \a s */
UniformScaling<double> Scaling(double s) { return UniformScaling<double>(s); }
/** Constructs a uniform scaling from scale factor \a s */
template<typename RealScalar> UniformScaling<std::complex<RealScalar> >
Scaling(const std::complex<RealScalar>& s)
{ return UniformScaling<std::complex<RealScalar> >(s); }
/** Constructs a 2D axis aligned scaling */
template<typename Scalar> DiagonalMatrix<Scalar,2>
Scaling(Scalar sx, Scalar sy)
{ return DiagonalMatrix<Scalar,2>(sx, sy); }
/** Constructs a 3D axis aligned scaling */
template<typename Scalar> DiagonalMatrix<Scalar,3>
Scaling(Scalar sx, Scalar sy, Scalar sz)
{ return DiagonalMatrix<Scalar,3>(sx, sy, sz); }
/** Constructs an axis aligned scaling expression from vector expression \a coeffs
* This is an alias for coeffs.asDiagonal()
*/
template<typename Derived>
const DiagonalMatrixWrapper<Derived> Scaling(const MatrixBase<Derived>& coeffs)
{ return coeffs.asDiagonal(); }
/** \addtogroup GeometryModule */
//@{
typedef Scaling<float, 2> Scaling2f;
typedef Scaling<double,2> Scaling2d;
typedef Scaling<float, 3> Scaling3f;
typedef Scaling<double,3> Scaling3d;
/** \deprecated */
typedef DiagonalMatrix<float, 2> AlignedScaling2f;
/** \deprecated */
typedef DiagonalMatrix<double,2> AlignedScaling2d;
/** \deprecated */
typedef DiagonalMatrix<float, 3> AlignedScaling3f;
/** \deprecated */
typedef DiagonalMatrix<double,3> AlignedScaling3d;
//@}
template<typename Scalar, int Dim>
inline typename Scaling<Scalar,Dim>::TransformType
Scaling<Scalar,Dim>::operator* (const TranslationType& t) const
{
TransformType res;
res.matrix().setZero();
res.linear().diagonal() = coeffs();
res.translation() = m_coeffs.cwise() * t.vector();
res(Dim,Dim) = Scalar(1);
return res;
}
template<typename Scalar, int Dim>
inline typename Scaling<Scalar,Dim>::TransformType
Scaling<Scalar,Dim>::operator* (const TransformType& t) const
{
TransformType res = t;
res.prescale(m_coeffs);
return res;
}
#endif // EIGEN_SCALING_H

View File

@@ -41,7 +41,14 @@ template< typename Other,
int HDim,
int OtherRows=Other::RowsAtCompileTime,
int OtherCols=Other::ColsAtCompileTime>
struct ei_transform_product_impl;
struct ei_transform_right_product_impl;
template< typename Other,
int Dim,
int HDim,
int OtherRows=Other::RowsAtCompileTime,
int OtherCols=Other::ColsAtCompileTime>
struct ei_transform_left_product_impl;
/** \geometry_module \ingroup GeometryModule
*
@@ -83,8 +90,6 @@ public:
typedef Block<MatrixType,Dim,1> TranslationPart;
/** corresponding translation type */
typedef Translation<Scalar,Dim> TranslationType;
/** corresponding scaling transformation type */
typedef Scaling<Scalar,Dim> ScalingType;
protected:
@@ -104,7 +109,7 @@ public:
}
inline explicit Transform(const TranslationType& t) { *this = t; }
inline explicit Transform(const ScalingType& s) { *this = s; }
inline explicit Transform(const UniformScaling<Scalar>& s) { *this = s; }
template<typename Derived>
inline explicit Transform(const RotationBase<Derived, Dim>& r) { *this = r; }
@@ -138,10 +143,13 @@ public:
construct_from_matrix<OtherDerived, int(OtherDerived::RowsAtCompileTime) == Dim>::run(this, other);
}
/** Set \c *this from a (Dim+1)^2 matrix. */
/** Set \c *this from a Dim^2 or (Dim+1)^2 matrix. */
template<typename OtherDerived>
inline Transform& operator=(const MatrixBase<OtherDerived>& other)
{ m_matrix = other; return *this; }
{
construct_from_matrix<OtherDerived, int(OtherDerived::RowsAtCompileTime) == Dim>::run(this, other);
return *this;
}
#ifdef EIGEN_QT_SUPPORT
inline Transform(const QMatrix& other);
@@ -175,24 +183,32 @@ public:
inline TranslationPart translation() { return m_matrix.template block<Dim,1>(0,Dim); }
/** \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 either:
* \li a vector of size Dim,
* \li an homogeneous vector of size Dim+1,
* \li a transformation matrix of size Dim+1 x Dim+1.
*/
*
* The right hand side \a other might be either:
* \li a vector of size Dim,
* \li an homogeneous vector of size Dim+1,
* \li a linear transformation matrix of size Dim x Dim
* \li a transformation matrix of size Dim+1 x Dim+1.
*/
// note: this function is defined here because some compilers cannot find the respective declaration
template<typename OtherDerived>
inline const typename ei_transform_product_impl<OtherDerived,_Dim,_Dim+1>::ResultType
inline const typename ei_transform_right_product_impl<OtherDerived,_Dim,_Dim+1>::ResultType
operator * (const MatrixBase<OtherDerived> &other) const
{ return ei_transform_product_impl<OtherDerived,Dim,HDim>::run(*this,other.derived()); }
{ return ei_transform_right_product_impl<OtherDerived,Dim,HDim>::run(*this,other.derived()); }
/** \returns the product expression of a transformation matrix \a a times a transform \a b
* The transformation matrix \a a must have a Dim+1 x Dim+1 sizes. */
template<typename OtherDerived>
friend inline const typename ProductReturnType<OtherDerived,MatrixType>::Type
*
* The right hand side \a other might be either:
* \li a linear transformation matrix of size Dim x Dim
* \li a transformation matrix of size Dim+1 x Dim+1.
*/
template<typename OtherDerived> friend
inline const typename ei_transform_left_product_impl<OtherDerived,_Dim,_Dim+1>::ResultType
operator * (const MatrixBase<OtherDerived> &a, const Transform &b)
{ return a.derived() * b.matrix(); }
{ return ei_transform_left_product_impl<OtherDerived,Dim,HDim>::run(a.derived(),b); }
template<typename OtherDerived>
inline Transform& operator*=(const MatrixBase<OtherDerived>& other) { return *this = *this * other; }
/** Contatenates two transformations */
inline const Transform
@@ -230,16 +246,17 @@ public:
inline Transform& operator*=(const TranslationType& t) { return translate(t.vector()); }
inline Transform operator*(const TranslationType& t) const;
inline Transform& operator=(const ScalingType& t);
inline Transform& operator*=(const ScalingType& s) { return scale(s.coeffs()); }
inline Transform operator*(const ScalingType& s) const;
friend inline Transform operator*(const LinearMatrixType& mat, const Transform& t)
{
Transform res = t;
res.matrix().row(Dim) = t.matrix().row(Dim);
res.matrix().template block<Dim,HDim>(0,0) = (mat * t.matrix().template block<Dim,HDim>(0,0)).lazy();
return res;
}
inline Transform& operator=(const UniformScaling<Scalar>& t);
inline Transform& operator*=(const UniformScaling<Scalar>& s) { return scale(s.factor()); }
inline Transform operator*(const UniformScaling<Scalar>& s) const;
// friend inline Transform operator*(const LinearMatrixType& mat, const Transform& t)
// {
// Transform res = t;
// res.matrix().row(Dim) = t.matrix().row(Dim);
// res.matrix().template block<Dim,HDim>(0,0) = (mat * t.matrix().template block<Dim,HDim>(0,0)).lazy();
// return res;
// }
template<typename Derived>
inline Transform& operator=(const RotationBase<Derived,Dim>& r);
@@ -558,19 +575,19 @@ inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const TranslationT
}
template<typename Scalar, int Dim>
inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const ScalingType& s)
inline Transform<Scalar,Dim>& Transform<Scalar,Dim>::operator=(const UniformScaling<Scalar>& s)
{
m_matrix.setZero();
linear().diagonal() = s.coeffs();
linear().diagonal().fill(s.factor());
m_matrix.coeffRef(Dim,Dim) = Scalar(1);
return *this;
}
template<typename Scalar, int Dim>
inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const ScalingType& s) const
inline Transform<Scalar,Dim> Transform<Scalar,Dim>::operator*(const UniformScaling<Scalar>& s) const
{
Transform res = *this;
res.scale(s.coeffs());
res.scale(s.factor());
return res;
}
@@ -722,8 +739,9 @@ Transform<Scalar,Dim>::inverse(TransformTraits traits) const
*** Specializations of operator* with a MatrixBase ***
*****************************************************/
// T * affine matrix
template<typename Other, int Dim, int HDim>
struct ei_transform_product_impl<Other,Dim,HDim, HDim,HDim>
struct ei_transform_right_product_impl<Other,Dim,HDim, HDim,HDim>
{
typedef Transform<typename Other::Scalar,Dim> TransformType;
typedef typename TransformType::MatrixType MatrixType;
@@ -732,8 +750,9 @@ struct ei_transform_product_impl<Other,Dim,HDim, HDim,HDim>
{ return tr.matrix() * other; }
};
// T * linear matrix
template<typename Other, int Dim, int HDim>
struct ei_transform_product_impl<Other,Dim,HDim, Dim,Dim>
struct ei_transform_right_product_impl<Other,Dim,HDim, Dim,Dim>
{
typedef Transform<typename Other::Scalar,Dim> TransformType;
typedef typename TransformType::MatrixType MatrixType;
@@ -748,8 +767,9 @@ struct ei_transform_product_impl<Other,Dim,HDim, Dim,Dim>
}
};
// T * homogeneous vector
template<typename Other, int Dim, int HDim>
struct ei_transform_product_impl<Other,Dim,HDim, HDim,1>
struct ei_transform_right_product_impl<Other,Dim,HDim, HDim,1>
{
typedef Transform<typename Other::Scalar,Dim> TransformType;
typedef typename TransformType::MatrixType MatrixType;
@@ -758,8 +778,9 @@ struct ei_transform_product_impl<Other,Dim,HDim, HDim,1>
{ return tr.matrix() * other; }
};
// T * vector
template<typename Other, int Dim, int HDim>
struct ei_transform_product_impl<Other,Dim,HDim, Dim,1>
struct ei_transform_right_product_impl<Other,Dim,HDim, Dim,1>
{
typedef typename Other::Scalar Scalar;
typedef Transform<Scalar,Dim> TransformType;
@@ -777,4 +798,31 @@ struct ei_transform_product_impl<Other,Dim,HDim, Dim,1>
* (Scalar(1) / ( (tr.matrix().template block<1,Dim>(Dim,0) * other).coeff(0) + tr.matrix().coeff(Dim,Dim))); }
};
// affine matrix * T
template<typename Other, int Dim, int HDim>
struct ei_transform_left_product_impl<Other,Dim,HDim, HDim,HDim>
{
typedef Transform<typename Other::Scalar,Dim> TransformType;
typedef typename TransformType::MatrixType MatrixType;
typedef typename ProductReturnType<MatrixType,Other>::Type ResultType;
static ResultType run(const Other& other,const TransformType& tr)
{ return other * tr.matrix(); }
};
// linear matrix * T
template<typename Other, int Dim, int HDim>
struct ei_transform_left_product_impl<Other,Dim,HDim, Dim,Dim>
{
typedef Transform<typename Other::Scalar,Dim> TransformType;
typedef typename TransformType::MatrixType MatrixType;
typedef TransformType ResultType;
static ResultType run(const Other& other, const TransformType& tr)
{
TransformType res;
res.matrix().row(Dim) = tr.matrix().row(Dim);
res.matrix().template corner<Dim,HDim>(TopLeft) = (other * tr.matrix().template corner<Dim,HDim>(TopLeft)).lazy();
return res;
}
};
#endif // EIGEN_TRANSFORM_H

View File

@@ -52,8 +52,6 @@ public:
typedef Matrix<Scalar,Dim,1> VectorType;
/** corresponding linear transformation matrix type */
typedef Matrix<Scalar,Dim,Dim> LinearMatrixType;
/** corresponding scaling transformation type */
typedef Scaling<Scalar,Dim> ScalingType;
/** corresponding affine transformation type */
typedef Transform<Scalar,Dim> TransformType;
@@ -80,7 +78,7 @@ public:
m_coeffs.y() = sy;
m_coeffs.z() = sz;
}
/** Constructs and initialize the scaling transformation from a vector of scaling coefficients */
/** Constructs and initialize the translation transformation from a vector of translation coefficients */
explicit inline Translation(const VectorType& vector) : m_coeffs(vector) {}
const VectorType& vector() const { return m_coeffs; }
@@ -90,24 +88,27 @@ public:
inline Translation operator* (const Translation& other) const
{ return Translation(m_coeffs + other.m_coeffs); }
/** Concatenates a translation and a scaling */
inline TransformType operator* (const ScalingType& other) const;
/** Concatenates a translation and a uniform scaling */
inline TransformType operator* (const UniformScaling<Scalar>& other) const;
/** Concatenates a translation and a linear transformation */
inline TransformType operator* (const LinearMatrixType& linear) const;
template<typename OtherDerived>
inline TransformType operator* (const MatrixBase<OtherDerived>& linear) const;
/** Concatenates a translation and a rotation */
template<typename Derived>
inline TransformType operator*(const RotationBase<Derived,Dim>& r) const
{ return *this * r.toRotationMatrix(); }
/** Concatenates a linear transformation and a translation */
/** \returns the concatenation of a linear transformation \a l with the translation \a t */
// its a nightmare to define a templated friend function outside its declaration
friend inline TransformType operator* (const LinearMatrixType& linear, const Translation& t)
template<typename OtherDerived> friend
inline TransformType operator*(const MatrixBase<OtherDerived>& linear, const Translation& t)
{
TransformType res;
res.matrix().setZero();
res.linear() = linear;
res.translation() = linear * t.m_coeffs;
res.linear() = linear.derived();
res.translation() = linear.derived() * t.m_coeffs;
res.matrix().row(Dim).setZero();
res(Dim,Dim) = Scalar(1);
return res;
@@ -160,26 +161,26 @@ typedef Translation<float, 3> Translation3f;
typedef Translation<double,3> Translation3d;
//@}
template<typename Scalar, int Dim>
inline typename Translation<Scalar,Dim>::TransformType
Translation<Scalar,Dim>::operator* (const ScalingType& other) const
Translation<Scalar,Dim>::operator* (const UniformScaling<Scalar>& other) const
{
TransformType res;
res.matrix().setZero();
res.linear().diagonal() = other.coeffs();
res.linear().diagonal().fill(other.factor());
res.translation() = m_coeffs;
res(Dim,Dim) = Scalar(1);
return res;
}
template<typename Scalar, int Dim>
template<typename OtherDerived>
inline typename Translation<Scalar,Dim>::TransformType
Translation<Scalar,Dim>::operator* (const LinearMatrixType& linear) const
Translation<Scalar,Dim>::operator* (const MatrixBase<OtherDerived>& linear) const
{
TransformType res;
res.matrix().setZero();
res.linear() = linear;
res.linear() = linear.derived();
res.translation() = m_coeffs;
res.matrix().row(Dim).setZero();
res(Dim,Dim) = Scalar(1);