smooth
A C++ library for Lie theory
Loading...
Searching...
No Matches
so2.hpp
1// Copyright (C) 2021-2022 Petter Nilsson. MIT License.
2
3#pragma once
4
5#include <complex>
6
7#include <Eigen/Core>
8
9#include "detail/macro.hpp"
10#include "detail/so2.hpp"
11#include "lie_group_base.hpp"
12
13SMOOTH_BEGIN_NAMESPACE
14
15// \cond
16template<typename Scalar>
17class SO3;
18// \endcond
19
60template<typename _Derived>
61class SO2Base : public LieGroupBase<_Derived>
62{
64
65protected:
66 SO2Base() = default;
67
68public:
69 SMOOTH_INHERIT_TYPEDEFS;
70
74 Scalar angle() const { return Base::log().x(); }
75
80 {
81 const auto & x = static_cast<const _Derived &>(*this).coeffs().y();
82 const auto & y = static_cast<const _Derived &>(*this).coeffs().x();
83
84 using std::atan2;
85 if (y <= 0.) {
86 return atan2(y, x);
87 } else {
88 return atan2(-y, -x) - Scalar(M_PI);
89 }
90 }
91
96 {
97 const auto & x = static_cast<const _Derived &>(*this).coeffs().y();
98 const auto & y = static_cast<const _Derived &>(*this).coeffs().x();
99
100 using std::atan2;
101 if (y >= 0.) {
102 return atan2(y, x);
103 } else {
104 return Scalar(M_PI) + atan2(-y, -x);
105 }
106 }
107
111 Eigen::Vector2<Scalar> unit_complex() const
112 {
113 return Eigen::Vector2<Scalar>(
114 static_cast<const _Derived &>(*this).coeffs().y(), static_cast<const _Derived &>(*this).coeffs().x());
115 }
116
120 std::complex<Scalar> u1() const
121 {
122 return std::complex<Scalar>(
123 static_cast<const _Derived &>(*this).coeffs().y(), static_cast<const _Derived &>(*this).coeffs().x());
124 }
125
129 template<typename EigenDerived>
130 Eigen::Vector2<Scalar> operator*(const Eigen::MatrixBase<EigenDerived> & v) const
131 {
132 return Base::matrix() * v;
133 }
134
142 template<typename EigenDerived>
143 Eigen::Matrix<Scalar, 2, 1> dr_action(const Eigen::MatrixBase<EigenDerived> & v) const
144 {
145 return Base::matrix() * Base::hat(Eigen::Vector<Scalar, 1>::Ones()) * v;
146 }
147
156 {
157 using std::cos, std::sin;
158
159 const Scalar yaw = Base::log().x();
160 return SO3<Scalar>(Eigen::Quaternion<Scalar>(cos(yaw / 2), 0, 0, sin(yaw / 2)));
161 }
162};
163
164// \cond
165template<typename _Scalar>
166class SO2;
167// \endcond
168
169// \cond
170template<typename _Scalar>
171struct liebase_info<SO2<_Scalar>>
172{
173 static constexpr bool is_mutable = true;
174
175 using Impl = SO2Impl<_Scalar>;
176 using Scalar = _Scalar;
177
178 template<typename NewScalar>
180};
181// \endcond
182
188template<typename _Scalar>
189class SO2 : public SO2Base<SO2<_Scalar>>
190{
191 using Base = SO2Base<SO2<_Scalar>>;
192 SMOOTH_GROUP_API(SO2);
193
194public:
203 SO2(const Scalar & qz, const Scalar & qw)
204 {
205 using std::sqrt;
206
207 const Scalar n = sqrt(qw * qw + qz * qz);
208 m_coeffs.x() = qz / n;
209 m_coeffs.y() = qw / n;
210 }
211
217 explicit SO2(const Scalar & angle)
218 {
219 using std::cos, std::sin;
220
221 m_coeffs.x() = sin(angle);
222 m_coeffs.y() = cos(angle);
223 }
224
232 explicit SO2(const std::complex<Scalar> & c)
233 {
234 using std::sqrt;
235
236 const Scalar n = sqrt(c.imag() * c.imag() + c.real() * c.real());
237 m_coeffs.x() = c.imag() / n;
238 m_coeffs.y() = c.real() / n;
239 }
240};
241
242// \cond
243template<typename _Scalar>
244struct liebase_info<Map<SO2<_Scalar>>> : public liebase_info<SO2<_Scalar>>
245{};
246// \endcond
247
253template<typename _Scalar>
254class Map<SO2<_Scalar>> : public SO2Base<Map<SO2<_Scalar>>>
255{
257
258 SMOOTH_MAP_API();
259};
260
261// \cond
262template<typename _Scalar>
263struct liebase_info<Map<const SO2<_Scalar>>> : public liebase_info<SO2<_Scalar>>
264{
265 static constexpr bool is_mutable = false;
266};
267// \endcond
268
274template<typename _Scalar>
275class Map<const SO2<_Scalar>> : public SO2Base<Map<const SO2<_Scalar>>>
276{
278
279 SMOOTH_CONST_MAP_API();
280};
281
282using SO2f = SO2<float>;
283using SO2d = SO2<double>;
284
285SMOOTH_END_NAMESPACE
286
287// Std format
288#if __has_include(<format>)
289#include <format>
290#include <string>
291
292template<class Scalar>
293struct std::formatter<smooth::SO2<Scalar>>
294{
295 std::string m_format;
296
297 constexpr auto parse(std::format_parse_context & ctx)
298 {
299 m_format = "{:";
300 for (auto it = ctx.begin(); it != ctx.end(); ++it) {
301 char c = *it;
302 m_format += c;
303 if (c == '}') return it;
304 }
305 return ctx.end();
306 }
307
308 auto format(const smooth::SO2<Scalar> & obj, std::format_context & ctx) const
309 {
310 return std::vformat_to(ctx.out(), m_format, std::make_format_args(obj.angle()));
311 }
312};
313
314#endif
Base class for Lie group types.
typename traits::Scalar Scalar
Scalar type.
Tangent log() const noexcept
Lie group logarithm.
static Matrix hat(const Eigen::MatrixBase< TangentDerived > &a) noexcept
Lie algebra hat map.
Matrix matrix() const noexcept
Return as matrix Lie group element in .
Eigen::Matrix< Scalar, Dim, Dim > Matrix
Lie group matrix type.
Memory mapping of internal Lie group types.
Base class for SO2 Lie group types.
Definition so2.hpp:62
std::complex< Scalar > u1() const
Unit complex number (U(1)) representation.
Definition so2.hpp:120
Eigen::Vector2< Scalar > unit_complex() const
Unit complex number (U(1)) representation.
Definition so2.hpp:111
Scalar angle_ccw() const
Angle representation in clockwise direction, in range.
Definition so2.hpp:95
Scalar angle() const
Angle representation, in range.
Definition so2.hpp:74
SO3< Scalar > lift_so3() const
Lift to SO3.
Definition so2.hpp:155
Scalar angle_cw() const
Angle representation in clockwise direction, in range.
Definition so2.hpp:79
Eigen::Vector2< Scalar > operator*(const Eigen::MatrixBase< EigenDerived > &v) const
Rotation action on 2D vector.
Definition so2.hpp:130
Eigen::Matrix< Scalar, 2, 1 > dr_action(const Eigen::MatrixBase< EigenDerived > &v) const
Jacobian of rotation action w.r.t. group.
Definition so2.hpp:143
Storage implementation of SO2 Lie group.
Definition so2.hpp:190
SO2(const std::complex< Scalar > &c)
Construct from unit complex number.
Definition so2.hpp:232
SO2(const Scalar &qz, const Scalar &qw)
Construct from coefficients.
Definition so2.hpp:203
SO2(const Scalar &angle)
Construct from angle.
Definition so2.hpp:217
Storage implementation of SO3 Lie group.
Definition so3.hpp:164
typename traits::man< M >::Scalar Scalar
Manifold scalar type.
Definition manifold.hpp:88
typename traits::man< M >::PlainObject PlainObject
Manifold default type.
Definition manifold.hpp:94
Type trait that maps a type to Lie group operations.