ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
quaternion.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef SRC_UTILS_INCLUDE_UTILS_QUATERNION_HPP
20#define SRC_UTILS_INCLUDE_UTILS_QUATERNION_HPP
21
22/**
23 * @file
24 *
25 * @brief Quaternion implementation and trait types
26 * for boost qvm interoperability.
27 */
28
29#include <boost/qvm/deduce_quat.hpp>
30#include <boost/qvm/deduce_scalar.hpp>
31#include <boost/qvm/deduce_vec.hpp>
32#include <boost/qvm/quat.hpp>
33#include <boost/qvm/quat_access.hpp>
34#include <boost/qvm/quat_operations.hpp>
35#include <boost/qvm/quat_traits.hpp>
36#include <boost/qvm/quat_vec_operations.hpp>
37
38#include <boost/serialization/array.hpp>
39#include <boost/serialization/is_bitwise_serializable.hpp>
40#include <boost/serialization/level.hpp>
41
42#include "utils/Array.hpp"
43#include "utils/Vector.hpp"
44#include "utils/matrix.hpp"
46
47#include <cassert>
48#include <cstddef>
49#include <type_traits>
50
51namespace Utils {
52
53/**
54 * Quaternion representation.
55 * @tparam T Element data type.
56 */
57template <typename T> struct Quaternion {
58 using container = typename Utils::Array<T, 4>;
60 using pointer = typename container::pointer;
61 using const_pointer = typename container::const_pointer;
62 using value_type = typename container::value_type;
63 using reference = typename container::reference;
64
65private:
67 template <class Archive> void serialize(Archive &ar, const unsigned int) {
68 ar & m_data;
69 }
70
71public:
72 /**
73 * @brief Normalize the quaternion in place.
74 */
75 void normalize() { boost::qvm::normalize(*this); }
76
77 /**
78 * @brief Retrieve a normalized copy of the quaternion.
79 * @return Normalized quaternion.
80 */
81 Quaternion<T> normalized() const { return boost::qvm::normalized(*this); }
82
83 /**
84 * @brief Element access (const).
85 * @param i Element index.
86 * @return Value of element @p i.
87 */
88 value_type operator[](std::size_t i) const { return m_data[i]; }
89 /**
90 * @brief Element access (non const).
91 * @param i Element index.
92 * @return Value of element @p i.
93 */
94 reference operator[](std::size_t i) { return m_data[i]; }
95
96 /**
97 * @brief Retrieve the norm of the quaternion.
98 * @return The norm.
99 */
100 value_type norm() const { return boost::qvm::mag(*this); }
101 /**
102 * @brief Retrieve the square of the norm of the quaternion.
103 * @return The squared norm.
104 */
105 value_type norm2() const { return boost::qvm::mag_sqr(*this); }
106
107 /**
108 * @brief Construct an identity quaternion.
109 * @return Identity quaternion.
110 */
111 static Quaternion<T> identity() { return boost::qvm::identity_quat<T>(); }
112
113 /**
114 * @brief Construct a zero quaternion.
115 * @return Quaternion with all elements set to zero.
116 */
117 static Quaternion<T> zero() { return boost::qvm::zero_quat<T>(); }
118
119 /**
120 * @brief Access to the underlying data (non const).
121 * @return Pointer to the first data member.
122 */
123 constexpr pointer data() { return m_data.data(); }
124
125 /**
126 * @brief Access to the underlying data (const).
127 * @return Pointer to the first data member.
128 */
129 constexpr const_pointer data() const noexcept { return m_data.data(); }
130};
131
132/**
133 * @brief Product quaternion and arithmetic type.
134 * @tparam T Data type of quaternion @p a.
135 * @tparam U Type of multiplier @p b.
136 * @param b Quaternion.
137 * @param a Multiplier.
138 * @return Multiplied quaternion.
139 */
140template <typename T, typename U,
141 std::enable_if_t<std::is_arithmetic_v<U>, bool> = true>
142Quaternion<T> operator*(const U &b, const Quaternion<T> &a) {
143 return boost::qvm::operator*(a, b);
144}
145
146/**
147 * @brief Convert quaternion to rotation matrix.
148 * @tparam T Data type of quaternion.
149 * @param q Quaternion.
150 * @return Rotation matrix.
151 */
152template <typename T> Matrix<T, 3, 3> rotation_matrix(Quaternion<T> const &q) {
153 auto const normed_q = q.normalized();
154 auto const id_mat = Utils::identity_mat<double, 3, 3>();
155 auto const v1 = normed_q * id_mat.col<0>();
156 auto const v2 = normed_q * id_mat.col<1>();
157 auto const v3 = normed_q * id_mat.col<2>();
158 return {{v1[0], v2[0], v3[0]}, {v1[1], v2[1], v3[1]}, {v1[2], v2[2], v3[2]}};
159}
160
161using boost::qvm::operator*;
162using boost::qvm::operator*=;
163using boost::qvm::operator==;
164using boost::qvm::dot;
165using boost::qvm::operator/;
166using boost::qvm::operator/=;
167using boost::qvm::operator+;
168using boost::qvm::operator+=;
169using boost::qvm::operator-;
170using boost::qvm::operator-=;
171
172} // namespace Utils
173
174namespace boost {
175
176namespace qvm {
177
178template <class T> struct quat_traits<Utils::Quaternion<T>> {
180 using scalar_type = T;
181
182 template <std::size_t I>
183 static constexpr inline scalar_type &write_element(quat_type &q) {
184 static_assert(I < 4, "Invalid index into quaternion.");
185 return q[I];
186 }
187
188 template <std::size_t I>
189 static constexpr inline scalar_type read_element(quat_type const &q) {
190 static_assert(I < 4, "Invalid index into quaternion.");
191 return q[I];
192 }
193
194 static inline scalar_type read_element_idx(std::size_t i,
195 quat_type const &q) {
196 assert(i < 4);
197 return q[i];
198 }
199
200 static inline scalar_type &write_element_idx(std::size_t i, quat_type &q) {
201 assert(i < 4);
202 return q[i];
203 }
204};
205
206template <typename T, typename U>
207struct deduce_scalar<Utils::Quaternion<T>, Utils::Quaternion<U>> {
208 using type = std::common_type_t<T, U>;
209};
210
211template <typename T, typename U, std::size_t N>
212struct deduce_scalar<Utils::Quaternion<T>, Utils::Vector<U, N>> {
213 using type = std::common_type_t<T, U>;
214};
215
216template <typename T, typename U>
217struct deduce_vec2<Utils::Quaternion<T>, Utils::Vector<U, 3>, 3> {
219};
220
221template <typename T> struct deduce_quat<Utils::Quaternion<T>> {
222 using type = typename Utils::Quaternion<T>;
223};
224
225template <typename T, typename U>
226struct deduce_quat2<Utils::Quaternion<T>, Utils::Quaternion<U>> {
228};
229
230} // namespace qvm
231
232} // namespace boost
233
235UTILS_ARRAY_BOOST_BIT_S(Utils::Quaternion, 0)
236UTILS_ARRAY_BOOST_CLASS(Utils::Quaternion, 0, object_serializable)
237UTILS_ARRAY_BOOST_TRACK(Utils::Quaternion, 0, track_never)
238
239#endif // SRC_UTILS_INCLUDE_UTILS_QUATERNION_HPP
Array implementation with CUDA support.
Vector implementation and trait types for boost qvm interoperability.
#define UTILS_ARRAY_BOOST_MPI_T(Container, N)
Mark array types as MPI data types.
Definition array.hpp:50
#define UTILS_ARRAY_BOOST_BIT_S(Container, N)
Mark array types as MPI bitwise serializable.
Definition array.hpp:63
#define UTILS_ARRAY_BOOST_CLASS(Container, N, ImplementationLevel)
Redefinition of BOOST_CLASS_IMPLEMENTATION for array types.
Definition array.hpp:78
#define UTILS_ARRAY_BOOST_TRACK(Container, N, TrackingLevel)
Redefinition of BOOST_CLASS_TRACKING for array types.
Definition array.hpp:97
Matrix implementation and trait types for boost qvm interoperability.
Quaternion< T > operator*(const U &b, const Quaternion< T > &a)
Product quaternion and arithmetic type.
Matrix< T, 3, 3 > rotation_matrix(Quaternion< T > const &q)
Convert quaternion to rotation matrix.
Matrix representation with static size.
Definition matrix.hpp:65
Quaternion representation.
typename container::const_pointer const_pointer
constexpr pointer data()
Access to the underlying data (non const).
typename container::pointer pointer
typename Utils::Array< T, 4 > container
static Quaternion< T > zero()
Construct a zero quaternion.
static Quaternion< T > identity()
Construct an identity quaternion.
value_type norm2() const
Retrieve the square of the norm of the quaternion.
Quaternion< T > normalized() const
Retrieve a normalized copy of the quaternion.
reference operator[](std::size_t i)
Element access (non const).
typename container::reference reference
value_type operator[](std::size_t i) const
Element access (const).
void normalize()
Normalize the quaternion in place.
typename container::value_type value_type
friend class boost::serialization::access
constexpr const_pointer data() const noexcept
Access to the underlying data (const).
value_type norm() const
Retrieve the norm of the quaternion.
typename Utils::Quaternion< std::common_type_t< T, U > > type
typename Utils::Vector< std::common_type_t< T, U >, 3 > type
static scalar_type read_element_idx(std::size_t i, quat_type const &q)
static scalar_type & write_element_idx(std::size_t i, quat_type &q)
static constexpr scalar_type & write_element(quat_type &q)
static constexpr scalar_type read_element(quat_type const &q)