Eigen  5.0.1
 
Loading...
Searching...
No Matches
AngleAxis.h
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// SPDX-License-Identifier: MPL-2.0
10
11#ifndef EIGEN_ANGLEAXIS_H
12#define EIGEN_ANGLEAXIS_H
13
14// IWYU pragma: private
15#include "./InternalHeaderCheck.h"
16
17namespace Eigen {
18
44
45namespace internal {
46template <typename Scalar_>
47struct traits<AngleAxis<Scalar_> > {
48 using Scalar = Scalar_;
49};
50} // namespace internal
51
52template <typename Scalar_>
53class AngleAxis : public RotationBase<AngleAxis<Scalar_>, 3> {
54 using Base = RotationBase<AngleAxis<Scalar_>, 3>;
55
56 public:
57 using Base::operator*;
58
59 enum { Dim = 3 };
61 using Scalar = Scalar_;
62 using Matrix3 = Matrix<Scalar, 3, 3>;
63 using Vector3 = Matrix<Scalar, 3, 1>;
64 using QuaternionType = Quaternion<Scalar>;
65
66 protected:
67 Vector3 m_axis;
68 Scalar m_angle;
69
70 public:
72 EIGEN_DEVICE_FUNC AngleAxis() {}
78 template <typename Derived>
79 EIGEN_DEVICE_FUNC inline AngleAxis(const Scalar& angle, const MatrixBase<Derived>& axis)
80 : m_axis(axis), m_angle(angle) {}
81
84 template <typename QuatDerived>
85 EIGEN_DEVICE_FUNC inline explicit AngleAxis(const QuaternionBase<QuatDerived>& q) {
86 *this = q;
87 }
88
89 template <typename Derived>
90 EIGEN_DEVICE_FUNC inline explicit AngleAxis(const MatrixBase<Derived>& m) {
91 *this = m;
92 }
93
95 EIGEN_DEVICE_FUNC Scalar angle() const { return m_angle; }
97 EIGEN_DEVICE_FUNC Scalar& angle() { return m_angle; }
98
100 EIGEN_DEVICE_FUNC const Vector3& axis() const { return m_axis; }
105 EIGEN_DEVICE_FUNC Vector3& axis() { return m_axis; }
106
108 EIGEN_DEVICE_FUNC inline QuaternionType operator*(const AngleAxis& other) const {
109 return QuaternionType(*this) * QuaternionType(other);
110 }
111
113 EIGEN_DEVICE_FUNC inline QuaternionType operator*(const QuaternionType& other) const {
114 return QuaternionType(*this) * other;
115 }
116
118 friend EIGEN_DEVICE_FUNC inline QuaternionType operator*(const QuaternionType& a, const AngleAxis& b) {
119 return a * QuaternionType(b);
120 }
121
123 EIGEN_DEVICE_FUNC AngleAxis inverse() const { return AngleAxis(-m_angle, m_axis); }
124
125 template <class QuatDerived>
126 EIGEN_DEVICE_FUNC AngleAxis& operator=(const QuaternionBase<QuatDerived>& q);
127 template <typename Derived>
128 EIGEN_DEVICE_FUNC AngleAxis& operator=(const MatrixBase<Derived>& m);
129
130 template <typename Derived>
131 EIGEN_DEVICE_FUNC AngleAxis& fromRotationMatrix(const MatrixBase<Derived>& m);
132 EIGEN_DEVICE_FUNC Matrix3 toRotationMatrix(void) const;
133
136 template <typename OtherVectorType>
137 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Vector3 _transformVector(const OtherVectorType& v) const {
138 EIGEN_USING_STD(sin)
139 EIGEN_USING_STD(cos)
140 eigen_assert(v.size() == 3);
141
142 // Rodrigues' rotation formula: v' = v*cos(θ) + (k×v)*sin(θ) + k*(k·v)*(1-cos(θ))
143 const Vector3 v3(v);
144 const Scalar c = cos(m_angle);
145 const Scalar s = sin(m_angle);
146 return v3 * c + m_axis.cross(v3) * s + m_axis * (m_axis.dot(v3) * (Scalar(1) - c));
147 }
148
154 template <typename NewScalarType>
155 EIGEN_DEVICE_FUNC inline typename internal::cast_return_type<AngleAxis, AngleAxis<NewScalarType> >::type cast()
156 const {
157 return typename internal::cast_return_type<AngleAxis, AngleAxis<NewScalarType> >::type(*this);
158 }
159
161 template <typename OtherScalarType>
162 EIGEN_DEVICE_FUNC inline explicit AngleAxis(const AngleAxis<OtherScalarType>& other) {
163 m_axis = other.axis().template cast<Scalar>();
164 m_angle = Scalar(other.angle());
165 }
166
167 EIGEN_DEVICE_FUNC static inline const AngleAxis Identity() { return AngleAxis(Scalar(0), Vector3::UnitX()); }
168
173 EIGEN_DEVICE_FUNC bool isApprox(const AngleAxis& other, const typename NumTraits<Scalar>::Real& prec =
174 NumTraits<Scalar>::dummy_precision()) const {
175 return m_axis.isApprox(other.m_axis, prec) && internal::isApprox(m_angle, other.m_angle, prec);
176 }
177};
178
185
192template <typename Scalar>
193template <typename QuatDerived>
194EIGEN_DEVICE_FUNC AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived>& q) {
195 EIGEN_USING_STD(atan2)
196 EIGEN_USING_STD(abs)
197 Scalar n = q.vec().norm();
198 if (n < NumTraits<Scalar>::epsilon()) n = q.vec().stableNorm();
199
200 if (n != Scalar(0)) {
201 m_angle = Scalar(2) * atan2(n, abs(q.w()));
202 if (q.w() < Scalar(0)) n = -n;
203 m_axis = q.vec() / n;
204 } else {
205 m_angle = Scalar(0);
206 m_axis << Scalar(1), Scalar(0), Scalar(0);
207 }
208 return *this;
209}
210
213template <typename Scalar>
214template <typename Derived>
215EIGEN_DEVICE_FUNC AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const MatrixBase<Derived>& mat) {
216 // A 4D vector holds quaternion coefficients; anything else is a 3x3 rotation matrix.
217 if (mat.size() == 4) {
218 return *this = QuaternionType(mat);
219 }
220 return fromRotationMatrix(mat);
221}
222
228template <typename Scalar>
229template <typename Derived>
230EIGEN_DEVICE_FUNC AngleAxis<Scalar>& AngleAxis<Scalar>::fromRotationMatrix(const MatrixBase<Derived>& mat) {
231 EIGEN_STATIC_ASSERT(
232 (std::is_same<Scalar, typename Derived::Scalar>::value),
233 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
234 eigen_assert(mat.cols() == 3 && mat.rows() == 3);
235
236 // Compute a (non-unit) quaternion proportional to the rotation using
237 // Shoemake's algorithm (shared with Quaternion::operator=(MatrixBase)),
238 // skipping the intermediate normalization since AngleAxis::operator=(QuaternionBase)
239 // normalizes the axis and uses atan2(|v|, |w|).
240 QuaternionType q;
241 internal::quaternionbase_assign_impl<Derived, 3, 3>::template run<false>(q, mat.derived());
242 return *this = q;
243}
244
247template <typename Scalar>
248typename AngleAxis<Scalar>::Matrix3 EIGEN_DEVICE_FUNC AngleAxis<Scalar>::toRotationMatrix(void) const {
249 EIGEN_USING_STD(sin)
250 EIGEN_USING_STD(cos)
251 Matrix3 res;
252 Vector3 sin_axis = sin(m_angle) * m_axis;
253 Scalar c = cos(m_angle);
254 Vector3 cos1_axis = (Scalar(1) - c) * m_axis;
255
256 Scalar tmp;
257 tmp = cos1_axis.x() * m_axis.y();
258 res.coeffRef(0, 1) = tmp - sin_axis.z();
259 res.coeffRef(1, 0) = tmp + sin_axis.z();
260
261 tmp = cos1_axis.x() * m_axis.z();
262 res.coeffRef(0, 2) = tmp + sin_axis.y();
263 res.coeffRef(2, 0) = tmp - sin_axis.y();
264
265 tmp = cos1_axis.y() * m_axis.z();
266 res.coeffRef(1, 2) = tmp - sin_axis.x();
267 res.coeffRef(2, 1) = tmp + sin_axis.x();
268
269 res.diagonal() = cos1_axis.cwiseProduct(m_axis).array() + c;
270
271 return res;
272}
273
274} // end namespace Eigen
275
276#endif // EIGEN_ANGLEAXIS_H
Represents a 3D rotation as a rotation angle around an arbitrary 3D axis.
Definition AngleAxis.h:53
QuaternionType operator*(const QuaternionType &other) const
Definition AngleAxis.h:113
AngleAxis(const AngleAxis< OtherScalarType > &other)
Definition AngleAxis.h:162
QuaternionType operator*(const AngleAxis &other) const
Definition AngleAxis.h:108
Scalar & angle()
Definition AngleAxis.h:97
Vector3 & axis()
Definition AngleAxis.h:105
AngleAxis(const QuaternionBase< QuatDerived > &q)
Definition AngleAxis.h:85
internal::cast_return_type< AngleAxis, AngleAxis< NewScalarType > >::type cast() const
Definition AngleAxis.h:155
Vector3 _transformVector(const OtherVectorType &v) const
Definition AngleAxis.h:137
AngleAxis(const Scalar &angle, const MatrixBase< Derived > &axis)
Definition AngleAxis.h:79
Scalar_ Scalar
Definition AngleAxis.h:61
AngleAxis(const MatrixBase< Derived > &m)
Definition AngleAxis.h:90
AngleAxis inverse() const
Definition AngleAxis.h:123
const Vector3 & axis() const
Definition AngleAxis.h:100
AngleAxis()
Definition AngleAxis.h:72
bool isApprox(const AngleAxis &other, const typename NumTraits< Scalar >::Real &prec=NumTraits< Scalar >::dummy_precision()) const
Definition AngleAxis.h:173
friend QuaternionType operator*(const QuaternionType &a, const AngleAxis &b)
Definition AngleAxis.h:118
Matrix3 toRotationMatrix(void) const
Definition AngleAxis.h:248
Scalar angle() const
Definition AngleAxis.h:95
const std::enable_if_t< std::is_same< typename LhsDerived::Scalar, typename RhsDerived::Scalar >::value, Eigen::CwiseBinaryOp< Eigen::internal::scalar_atan2_op< typename LhsDerived::Scalar, typename RhsDerived::Scalar >, const LhsDerived, const RhsDerived > > atan2(const Eigen::ArrayBase< LhsDerived > &x, const Eigen::ArrayBase< RhsDerived > &exponents)
Definition GlobalFunctions.h:222
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:53
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:188
constexpr Scalar & coeffRef(Index rowId, Index colId)
Definition PlainObjectBase.h:205
Base class for quaternion expressions.
Definition Quaternion.h:36
const VectorBlock< const Coefficients, 3 > vec() const
Definition Quaternion.h:78
constexpr CoeffReturnType w() const
Definition Quaternion.h:66
The quaternion class used to represent 3D orientations and rotations.
Definition Quaternion.h:304
Common base class for compact rotation representations.
Definition RotationBase.h:33
AngleAxis< double > AngleAxisd
Definition AngleAxis.h:184
AngleAxis< float > AngleAxisf
Definition AngleAxis.h:181