1*bf2c3715SXin Li // This file is part of Eigen, a lightweight C++ template library 2*bf2c3715SXin Li // for linear algebra. 3*bf2c3715SXin Li // 4*bf2c3715SXin Li // Copyright (C) 2008 Gael Guennebaud <[email protected]> 5*bf2c3715SXin Li // 6*bf2c3715SXin Li // This Source Code Form is subject to the terms of the Mozilla 7*bf2c3715SXin Li // Public License v. 2.0. If a copy of the MPL was not distributed 8*bf2c3715SXin Li // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9*bf2c3715SXin Li 10*bf2c3715SXin Li #ifndef EIGEN_TRANSLATION_H 11*bf2c3715SXin Li #define EIGEN_TRANSLATION_H 12*bf2c3715SXin Li 13*bf2c3715SXin Li namespace Eigen { 14*bf2c3715SXin Li 15*bf2c3715SXin Li /** \geometry_module \ingroup Geometry_Module 16*bf2c3715SXin Li * 17*bf2c3715SXin Li * \class Translation 18*bf2c3715SXin Li * 19*bf2c3715SXin Li * \brief Represents a translation transformation 20*bf2c3715SXin Li * 21*bf2c3715SXin Li * \tparam _Scalar the scalar type, i.e., the type of the coefficients. 22*bf2c3715SXin Li * \tparam _Dim the dimension of the space, can be a compile time value or Dynamic 23*bf2c3715SXin Li * 24*bf2c3715SXin Li * \note This class is not aimed to be used to store a translation transformation, 25*bf2c3715SXin Li * but rather to make easier the constructions and updates of Transform objects. 26*bf2c3715SXin Li * 27*bf2c3715SXin Li * \sa class Scaling, class Transform 28*bf2c3715SXin Li */ 29*bf2c3715SXin Li template<typename _Scalar, int _Dim> 30*bf2c3715SXin Li class Translation 31*bf2c3715SXin Li { 32*bf2c3715SXin Li public: 33*bf2c3715SXin Li EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim) 34*bf2c3715SXin Li /** dimension of the space */ 35*bf2c3715SXin Li enum { Dim = _Dim }; 36*bf2c3715SXin Li /** the scalar type of the coefficients */ 37*bf2c3715SXin Li typedef _Scalar Scalar; 38*bf2c3715SXin Li /** corresponding vector type */ 39*bf2c3715SXin Li typedef Matrix<Scalar,Dim,1> VectorType; 40*bf2c3715SXin Li /** corresponding linear transformation matrix type */ 41*bf2c3715SXin Li typedef Matrix<Scalar,Dim,Dim> LinearMatrixType; 42*bf2c3715SXin Li /** corresponding affine transformation type */ 43*bf2c3715SXin Li typedef Transform<Scalar,Dim,Affine> AffineTransformType; 44*bf2c3715SXin Li /** corresponding isometric transformation type */ 45*bf2c3715SXin Li typedef Transform<Scalar,Dim,Isometry> IsometryTransformType; 46*bf2c3715SXin Li 47*bf2c3715SXin Li protected: 48*bf2c3715SXin Li 49*bf2c3715SXin Li VectorType m_coeffs; 50*bf2c3715SXin Li 51*bf2c3715SXin Li public: 52*bf2c3715SXin Li 53*bf2c3715SXin Li /** Default constructor without initialization. */ Translation()54*bf2c3715SXin Li EIGEN_DEVICE_FUNC Translation() {} 55*bf2c3715SXin Li /** */ Translation(const Scalar & sx,const Scalar & sy)56*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline Translation(const Scalar& sx, const Scalar& sy) 57*bf2c3715SXin Li { 58*bf2c3715SXin Li eigen_assert(Dim==2); 59*bf2c3715SXin Li m_coeffs.x() = sx; 60*bf2c3715SXin Li m_coeffs.y() = sy; 61*bf2c3715SXin Li } 62*bf2c3715SXin Li /** */ Translation(const Scalar & sx,const Scalar & sy,const Scalar & sz)63*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline Translation(const Scalar& sx, const Scalar& sy, const Scalar& sz) 64*bf2c3715SXin Li { 65*bf2c3715SXin Li eigen_assert(Dim==3); 66*bf2c3715SXin Li m_coeffs.x() = sx; 67*bf2c3715SXin Li m_coeffs.y() = sy; 68*bf2c3715SXin Li m_coeffs.z() = sz; 69*bf2c3715SXin Li } 70*bf2c3715SXin Li /** Constructs and initialize the translation transformation from a vector of translation coefficients */ Translation(const VectorType & vector)71*bf2c3715SXin Li EIGEN_DEVICE_FUNC explicit inline Translation(const VectorType& vector) : m_coeffs(vector) {} 72*bf2c3715SXin Li 73*bf2c3715SXin Li /** \brief Returns the x-translation by value. **/ x()74*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline Scalar x() const { return m_coeffs.x(); } 75*bf2c3715SXin Li /** \brief Returns the y-translation by value. **/ y()76*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline Scalar y() const { return m_coeffs.y(); } 77*bf2c3715SXin Li /** \brief Returns the z-translation by value. **/ z()78*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline Scalar z() const { return m_coeffs.z(); } 79*bf2c3715SXin Li 80*bf2c3715SXin Li /** \brief Returns the x-translation as a reference. **/ x()81*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline Scalar& x() { return m_coeffs.x(); } 82*bf2c3715SXin Li /** \brief Returns the y-translation as a reference. **/ y()83*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline Scalar& y() { return m_coeffs.y(); } 84*bf2c3715SXin Li /** \brief Returns the z-translation as a reference. **/ z()85*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline Scalar& z() { return m_coeffs.z(); } 86*bf2c3715SXin Li vector()87*bf2c3715SXin Li EIGEN_DEVICE_FUNC const VectorType& vector() const { return m_coeffs; } vector()88*bf2c3715SXin Li EIGEN_DEVICE_FUNC VectorType& vector() { return m_coeffs; } 89*bf2c3715SXin Li translation()90*bf2c3715SXin Li EIGEN_DEVICE_FUNC const VectorType& translation() const { return m_coeffs; } translation()91*bf2c3715SXin Li EIGEN_DEVICE_FUNC VectorType& translation() { return m_coeffs; } 92*bf2c3715SXin Li 93*bf2c3715SXin Li /** Concatenates two translation */ 94*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline Translation operator* (const Translation& other) const 95*bf2c3715SXin Li { return Translation(m_coeffs + other.m_coeffs); } 96*bf2c3715SXin Li 97*bf2c3715SXin Li /** Concatenates a translation and a uniform scaling */ 98*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline AffineTransformType operator* (const UniformScaling<Scalar>& other) const; 99*bf2c3715SXin Li 100*bf2c3715SXin Li /** Concatenates a translation and a linear transformation */ 101*bf2c3715SXin Li template<typename OtherDerived> 102*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline AffineTransformType operator* (const EigenBase<OtherDerived>& linear) const; 103*bf2c3715SXin Li 104*bf2c3715SXin Li /** Concatenates a translation and a rotation */ 105*bf2c3715SXin Li template<typename Derived> 106*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline IsometryTransformType operator*(const RotationBase<Derived,Dim>& r) const 107*bf2c3715SXin Li { return *this * IsometryTransformType(r); } 108*bf2c3715SXin Li 109*bf2c3715SXin Li /** \returns the concatenation of a linear transformation \a l with the translation \a t */ 110*bf2c3715SXin Li // its a nightmare to define a templated friend function outside its declaration 111*bf2c3715SXin Li template<typename OtherDerived> friend 112*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline AffineTransformType operator*(const EigenBase<OtherDerived>& linear, const Translation& t) 113*bf2c3715SXin Li { 114*bf2c3715SXin Li AffineTransformType res; 115*bf2c3715SXin Li res.matrix().setZero(); 116*bf2c3715SXin Li res.linear() = linear.derived(); 117*bf2c3715SXin Li res.translation() = linear.derived() * t.m_coeffs; 118*bf2c3715SXin Li res.matrix().row(Dim).setZero(); 119*bf2c3715SXin Li res(Dim,Dim) = Scalar(1); 120*bf2c3715SXin Li return res; 121*bf2c3715SXin Li } 122*bf2c3715SXin Li 123*bf2c3715SXin Li /** Concatenates a translation and a transformation */ 124*bf2c3715SXin Li template<int Mode, int Options> 125*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline Transform<Scalar,Dim,Mode> operator* (const Transform<Scalar,Dim,Mode,Options>& t) const 126*bf2c3715SXin Li { 127*bf2c3715SXin Li Transform<Scalar,Dim,Mode> res = t; 128*bf2c3715SXin Li res.pretranslate(m_coeffs); 129*bf2c3715SXin Li return res; 130*bf2c3715SXin Li } 131*bf2c3715SXin Li 132*bf2c3715SXin Li /** Applies translation to vector */ 133*bf2c3715SXin Li template<typename Derived> 134*bf2c3715SXin Li inline typename internal::enable_if<Derived::IsVectorAtCompileTime,VectorType>::type 135*bf2c3715SXin Li operator* (const MatrixBase<Derived>& vec) const 136*bf2c3715SXin Li { return m_coeffs + vec.derived(); } 137*bf2c3715SXin Li 138*bf2c3715SXin Li /** \returns the inverse translation (opposite) */ inverse()139*bf2c3715SXin Li Translation inverse() const { return Translation(-m_coeffs); } 140*bf2c3715SXin Li Identity()141*bf2c3715SXin Li static const Translation Identity() { return Translation(VectorType::Zero()); } 142*bf2c3715SXin Li 143*bf2c3715SXin Li /** \returns \c *this with scalar type casted to \a NewScalarType 144*bf2c3715SXin Li * 145*bf2c3715SXin Li * Note that if \a NewScalarType is equal to the current scalar type of \c *this 146*bf2c3715SXin Li * then this function smartly returns a const reference to \c *this. 147*bf2c3715SXin Li */ 148*bf2c3715SXin Li template<typename NewScalarType> cast()149*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline typename internal::cast_return_type<Translation,Translation<NewScalarType,Dim> >::type cast() const 150*bf2c3715SXin Li { return typename internal::cast_return_type<Translation,Translation<NewScalarType,Dim> >::type(*this); } 151*bf2c3715SXin Li 152*bf2c3715SXin Li /** Copy constructor with scalar type conversion */ 153*bf2c3715SXin Li template<typename OtherScalarType> Translation(const Translation<OtherScalarType,Dim> & other)154*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline explicit Translation(const Translation<OtherScalarType,Dim>& other) 155*bf2c3715SXin Li { m_coeffs = other.vector().template cast<Scalar>(); } 156*bf2c3715SXin Li 157*bf2c3715SXin Li /** \returns \c true if \c *this is approximately equal to \a other, within the precision 158*bf2c3715SXin Li * determined by \a prec. 159*bf2c3715SXin Li * 160*bf2c3715SXin Li * \sa MatrixBase::isApprox() */ 161*bf2c3715SXin Li EIGEN_DEVICE_FUNC bool isApprox(const Translation& other, const typename NumTraits<Scalar>::Real& prec = NumTraits<Scalar>::dummy_precision()) const 162*bf2c3715SXin Li { return m_coeffs.isApprox(other.m_coeffs, prec); } 163*bf2c3715SXin Li 164*bf2c3715SXin Li }; 165*bf2c3715SXin Li 166*bf2c3715SXin Li /** \addtogroup Geometry_Module */ 167*bf2c3715SXin Li //@{ 168*bf2c3715SXin Li typedef Translation<float, 2> Translation2f; 169*bf2c3715SXin Li typedef Translation<double,2> Translation2d; 170*bf2c3715SXin Li typedef Translation<float, 3> Translation3f; 171*bf2c3715SXin Li typedef Translation<double,3> Translation3d; 172*bf2c3715SXin Li //@} 173*bf2c3715SXin Li 174*bf2c3715SXin Li template<typename Scalar, int Dim> 175*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline typename Translation<Scalar,Dim>::AffineTransformType 176*bf2c3715SXin Li Translation<Scalar,Dim>::operator* (const UniformScaling<Scalar>& other) const 177*bf2c3715SXin Li { 178*bf2c3715SXin Li AffineTransformType res; 179*bf2c3715SXin Li res.matrix().setZero(); 180*bf2c3715SXin Li res.linear().diagonal().fill(other.factor()); 181*bf2c3715SXin Li res.translation() = m_coeffs; 182*bf2c3715SXin Li res(Dim,Dim) = Scalar(1); 183*bf2c3715SXin Li return res; 184*bf2c3715SXin Li } 185*bf2c3715SXin Li 186*bf2c3715SXin Li template<typename Scalar, int Dim> 187*bf2c3715SXin Li template<typename OtherDerived> 188*bf2c3715SXin Li EIGEN_DEVICE_FUNC inline typename Translation<Scalar,Dim>::AffineTransformType 189*bf2c3715SXin Li Translation<Scalar,Dim>::operator* (const EigenBase<OtherDerived>& linear) const 190*bf2c3715SXin Li { 191*bf2c3715SXin Li AffineTransformType res; 192*bf2c3715SXin Li res.matrix().setZero(); 193*bf2c3715SXin Li res.linear() = linear.derived(); 194*bf2c3715SXin Li res.translation() = m_coeffs; 195*bf2c3715SXin Li res.matrix().row(Dim).setZero(); 196*bf2c3715SXin Li res(Dim,Dim) = Scalar(1); 197*bf2c3715SXin Li return res; 198*bf2c3715SXin Li } 199*bf2c3715SXin Li 200*bf2c3715SXin Li } // end namespace Eigen 201*bf2c3715SXin Li 202*bf2c3715SXin Li #endif // EIGEN_TRANSLATION_H 203