Skip to main content

quat.ixx File

Quaternion type for floating-point scalar types. More...

Included Headers

#include <cmath> #include <concepts> #include <helios.math.types:mat4>

Namespaces Index

namespacehelios
namespacemath

Classes Index

structIntrinsic

Marker tag for intrinsic Euler-angle composition. More...

structExtrinsic

Marker tag for extrinsic Euler-angle composition. More...

classquat<T>

Quaternion with scalar part w and vector part v. More...

Description

Quaternion type for floating-point scalar types.

File Listing

The file content with the documentation metadata removed is:

1
5module;
6
7
8#include <cmath>
9#include <concepts>
10
11export module helios.math.types:quat;
12
13import :vec3;
14import :mat4;
15
16
17export namespace helios::math {
18
22 struct Intrinsic{};
23
27 struct Extrinsic{};
28
34 template<typename T>
35 requires std::floating_point<T>
36 class quat {
37
38 T w_;
39
40 vec3<T> v_;
41
42
43 public:
44
54 template<typename TFrameRelation>
55 requires (std::same_as<TFrameRelation, Intrinsic> || std::same_as<TFrameRelation, Extrinsic>)
56 static constexpr quat<T> fromEulerAngles(const T xAngle, const T yAngle, const T zAngle) noexcept {
57
58 const auto x = vec3<T>{static_cast<T>(1), static_cast<T>(0), static_cast<T>(0)};
59 const auto y = vec3<T>{static_cast<T>(0), static_cast<T>(1), static_cast<T>(0)};
60 const auto z = vec3<T>{static_cast<T>(0), static_cast<T>(0), static_cast<T>(1)};
61
62 if constexpr (std::same_as<TFrameRelation, Intrinsic>) {
63 return (fromAxisAngle(x, xAngle) * fromAxisAngle(y, yAngle) * fromAxisAngle(z, zAngle)).normalized();
64 } else {
65 return (fromAxisAngle(z, zAngle) * fromAxisAngle(y, yAngle) * fromAxisAngle(x, xAngle)).normalized();
66 }
67
68 }
69
75 static constexpr quat<T> identity() noexcept {
76 return quat<T>{vec3<T>{static_cast<T>(0), static_cast<T>(0), static_cast<T>(0)}, static_cast<T>(1)};
77 }
78
86 static constexpr quat<T> fromAxisAngle(const helios::math::vec3<T> v, const T angle) noexcept {
87
88 const auto rad = angle * static_cast<T>(0.5);
89
90 return quat<T>{
91 std::sin(rad) * v.normalize(),
92 std::cos(rad)
93 };
94
95 }
96
103 explicit constexpr quat(const vec3<T> v, const T w) noexcept
104 : w_(w), v_(v) {}
105
106
113 constexpr quat<T> operator*(const quat<T>& other) const noexcept {
114
115 const auto v = v_.cross(other.v_) + w_ * other.v_ + other.w_ * v_;
116
117 const auto w = w_ * other.w_ - dot(v_, other.v_);
118
119 return quat<T>{v, w};
120 }
121
127 [[nodiscard]] constexpr quat<T> conjugate() const noexcept {
128 return quat<T>{v_ * static_cast<T>(-1), w_};
129 }
130
131
137 [[nodiscard]] constexpr T w() const noexcept {
138 return w_;
139 }
140
146 [[nodiscard]] constexpr vec3<T> v() const noexcept {
147 return v_;
148 }
149
155 [[nodiscard]] constexpr T length() const noexcept {
156 return static_cast<T>(std::sqrt(
157 v_[0] * v_[0] + v_[1] * v_[1] + v_[2] * v_[2] + w_ * w_
158 ));
159 }
160
166 [[nodiscard]] constexpr quat<T> normalized() const noexcept {
167 const auto l = length();
168 return quat<T>{v_ * (static_cast<T>(1) / l), w_ / l};
169 }
170
176 [[nodiscard]] constexpr mat4<T> rotationMatrix() const noexcept {
177
178 const auto q_norm = normalized();
179 const auto v = q_norm.v();
180 const auto w = q_norm.w();
181
182 const auto x2 = v[0] * v[0];
183 const auto y2 = v[1] * v[1];
184 const auto z2 = v[2] * v[2];
185 const auto xy = v[0] * v[1];
186 const auto xz = v[0] * v[2];
187 const auto yz = v[1] * v[2];
188 const auto wx = w * v[0];
189 const auto wy = w * v[1];
190 const auto wz = w * v[2];
191
192 return mat4<T>{
193 static_cast<T>(1) - static_cast<T>(2) * (y2 + z2),
194 static_cast<T>(2) * (xy + wz),
195 static_cast<T>(2) * (xz - wy),
196 static_cast<T>(0),
197
198 static_cast<T>(2) * (xy - wz),
199 static_cast<T>(1) - static_cast<T>(2) * (x2 + z2),
200 static_cast<T>(2) * (yz + wx),
201 static_cast<T>(0),
202
203 static_cast<T>(2) * (xz + wy),
204 static_cast<T>(2) * (yz - wx),
205 static_cast<T>(1) - static_cast<T>(2) * (x2 + y2),
206 static_cast<T>(0),
207
208 static_cast<T>(0),
209 static_cast<T>(0),
210 static_cast<T>(0),
211 static_cast<T>(1)
212 };
213
214 }
215
222 [[nodiscard]] constexpr vec3<T> rotate(const vec3<T> v) const noexcept {
223 const auto q_norm = normalized();
224 const auto other = quat<T>{v, 0};
225
226 return (q_norm * other * q_norm.conjugate()).v() ;
227 }
228
229
230 };
231
236
241
242}

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.9.8.