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