GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
math_quaternion.h
[詳解]
1
3
4// Copyright(c) 2023-2025 Design Engineering Laboratory, Saitama University
5// Released under the MIT license
6// https://opensource.org/licenses/mit-license.php
7
8#ifndef DESIGNLAB_MATH_QUATERNION_H_
9#define DESIGNLAB_MATH_QUATERNION_H_
10
11#include <cmath>
12#include <string>
13
14#include "cassert_define.h"
15#include "math_euler.h"
16#include "math_util.h"
17#include "math_vector3.h"
18
19
20namespace designlab
21{
22
37struct Quaternion final
38{
40 constexpr Quaternion() : w(1.0f), v(0.0f, 0.0f, 0.0f) {}
41
49 constexpr Quaternion(const float w_,
50 const float x_, const float y_, const float z_) :
51 w(w_),
52 v(x_, y_, z_) {}
53
59 constexpr Quaternion(const float w_, const Vector3& v_) : w(w_), v(v_) {}
60
62 constexpr Quaternion(const Quaternion& q) = default;
63
65 constexpr Quaternion(Quaternion&& q) noexcept = default;
66
68 constexpr Quaternion& operator =(const Quaternion& q) = default;
69
70 constexpr Quaternion operator + () const noexcept { return *this; }
71 constexpr Quaternion operator - () const noexcept { return { -w, -v }; }
72 constexpr Quaternion operator + (const Quaternion& q) const noexcept
73 {
74 return { w + q.w, v + q.v };
75 }
76 constexpr Quaternion operator - (const Quaternion& q) const noexcept
77 {
78 return { w - q.w, v - q.v };
79 }
80 constexpr Quaternion operator * (const Quaternion& q) const noexcept
81 {
82 return { w * q.w - v.Dot(q.v), w * q.v + q.w * v + v.Cross(q.v) };
83 }
84 constexpr Quaternion operator * (const float s) const noexcept
85 {
86 return { w * s, v * s };
87 }
88 constexpr Quaternion operator / (const float s) const
89 {
90 return { w / s, v / s };
91 }
92
93 bool operator == (const Quaternion& q) const noexcept
94 {
95 return math_util::IsEqual(w, q.w) && (v == q.v);
96 }
97 bool operator != (const Quaternion& q) const noexcept { return !(*this == q); }
98
99 bool operator < (const Quaternion& q) const noexcept
100 {
101 return (w < q.w) || (w == q.w && v < q.v);
102 }
103 bool operator > (const Quaternion& other) const noexcept
104 {
105 return other < *this;
106 }
107
108 bool operator <= (const Quaternion& other) const noexcept
109 {
110 return !(*this > other);
111 }
112
113 bool operator >= (const Quaternion& other) const noexcept
114 {
115 return !(*this < other);
116 }
117
118
123 [[nodiscard]]
124 constexpr float Dot(Quaternion other) const noexcept
125 {
126 return w * other.w + v.Dot(other.v);
127 }
128
134 [[nodiscard]]
135 constexpr Quaternion GetConjugate() const noexcept { return { w, -v }; }
136
140 [[nodiscard]]
141 constexpr float GetLengthSquared() const noexcept
142 {
143 return w * w + v.Dot(v);
144 }
145
150 [[nodiscard]]
151 inline float GetNorm() const noexcept
152 {
153 return std::sqrt(GetLengthSquared());
154 }
155
160 [[nodiscard]]
161 inline Quaternion GetInverse() const
162 {
163 return GetConjugate() * (1 / GetNorm());
164 }
165
170 [[nodiscard]] Quaternion GetNormalized() const noexcept;
171
175 [[nodiscard]]
176 constexpr float GetDistanceSquared(const Quaternion& q) const noexcept
177 {
178 return (*this - q).GetLengthSquared();
179 }
180
182 inline void Normalize() noexcept { *this = GetNormalized(); }
183
189 [[nodiscard]] constexpr Quaternion ToLeftHandCoordinate() const noexcept
190 {
191 return { w, v.x, -v.y, v.z };
192 }
193
200 [[nodiscard]]
201 static Quaternion MakeByAngleAxis(float rad_angle, const Vector3& axis);
202
203
207 [[nodiscard]] std::string ToString() const;
208
212 [[nodiscard]] std::string ToCsvString() const;
213
214 float w;
216};
217
218
219constexpr Quaternion operator * (float s, const Quaternion& q) { return q * s; }
220
222template <class Char>
223inline std::basic_ostream<Char>& operator <<(
224 std::basic_ostream<Char>& os, const Quaternion& q)
225{
226 os << math_util::FloatingPointNumToString(q.w) << Char(',') << q.v;
227
228 return os;
229}
230
232template <class Char>
233inline std::basic_istream<Char>& operator >>(
234 std::basic_istream<Char>& is, Quaternion& q)
235{
236 Char unused = 0;
237 return is >> unused >> q.w >> unused >> q.v;
238}
239
246[[nodiscard]]
247constexpr Vector3 RotateVector3(const Vector3& vec, const Quaternion& q)
248{
249 // 回転させるベクトルをスカラーが0のクオータニオンに変換.
250 const Quaternion p{ 0, vec.x, vec.y, vec.z };
251
252 // 正規化されたクォータニオンを使う場合は,共役と逆数が等しいので,
253 // 計算量を減らすことができる.
254
255 // 正規化されたクォータニオンを使う場合は,正規化されたクォータニオンを渡す必要がある.
256 assert(math_util::IsEqual(q.GetNorm(), 1.0f));
257
258 return (q * p * q.GetConjugate()).v; // ベクトル成分を返す.
259}
260
266Quaternion SlerpQuaternion(const Quaternion& q1, const Quaternion& q2, float t);
267
268} // namespace designlab
269
270
271#endif // DESIGNLAB_MATH_QUATERNION_H_
std::string FloatingPointNumToString(const T num, const int digit=kDigit, const int width=kWidth)
小数を文字列に変換する関数. C++ では C のフォーマットのように %3.3f とかで小数を文字列に変換できないため自作する.
Definition math_util.h:161
constexpr bool IsEqual(const T num1, const T num2) noexcept
C++において,小数同士の計算は誤差が出てしまう. 誤差込みで値が等しいか調べる.
Definition math_util.h:45
constexpr Quaternion operator*(float s, const Quaternion &q)
Vector3 RotateVector3(const Vector3 &vec, const EulerXYZ &rot)
回転させたベクトルを返す.三角関数の処理が多く重たいので注意.
std::basic_istream< Char > & operator>>(std::basic_istream< Char > &is, EulerXYZ &r)
入力ストリーム
Definition math_euler.h:128
Quaternion SlerpQuaternion(const Quaternion &q1, const Quaternion &q2, const float t)
球面線形補間を行う.
std::basic_ostream< Char > & operator<<(std::basic_ostream< Char > &os, const EulerXYZ &r)
出力ストリーム.Csv形式で出力する.カンマ区切り.単位は [rad].
Definition math_euler.h:117
クォータニオンを表す構造体.
bool operator<=(const Quaternion &other) const noexcept
bool operator==(const Quaternion &q) const noexcept
constexpr float GetLengthSquared() const noexcept
クォータニオンの長さの2乗を返す(ノルムの2乗). クォータニオンの長さの2乗は,w^2 + x^2 + y^2 + z^2 で求められる.
constexpr Quaternion & operator=(const Quaternion &q)=default
コピー代入演算子.
Quaternion GetNormalized() const noexcept
正規化したクォータニオンを返す. クォータニオンの正規化とは,ノルムを1にすることを表す. クォータニオンqの正規化は,q / |q| で求められる.
constexpr Quaternion(const float w_, const Vector3 &v_)
スカラー成分とベクトル成分を指定して初期化する. ノルムが1になるように代入すること, 使用は非推奨,MakeByAngleAxisを使うこと.
bool operator>(const Quaternion &other) const noexcept
std::string ToString() const
クォータニオンを文字列に変換する. w, x, y, z の順で出力する.
void Normalize() noexcept
自身を正規化する.ノルムが1になる.
constexpr Quaternion(Quaternion &&q) noexcept=default
ムーブコンストラクタ.
constexpr Quaternion operator/(const float s) const
static Quaternion MakeByAngleAxis(float rad_angle, const Vector3 &axis)
回転軸と回転角からクォータニオンを作成する. q = cos(θ/2) * w + sin(θ/2) * { v.x + v.y + v.z } となる. ノルムは必ず1になる.
float GetNorm() const noexcept
クォータニオンのノルムを返す. ノルムとは,ベクトルの大きさのこと. クォータニオンのノルムは,w^2 + x^2 + y^2 + z^2 の平方根で求められる.
Vector3 v
ベクトル成分.
bool operator>=(const Quaternion &other) const noexcept
constexpr Quaternion ToLeftHandCoordinate() const noexcept
左手座標系への変換を行う. 言うまでもないが,機械工学では通例右手座標系を使う. しかし,dxlib は左手座標系なので,dxlib で描画するときは, この関数を使って左手座標系に変換する必要があ...
constexpr Quaternion GetConjugate() const noexcept
クォータニオンの共役を返す. 共役なクォータニオンとは,ベクトル成分の符号を反転させたもの q = w + xi + yj + zk とすると, qの共役は w - xi - yj - zk となる...
constexpr Quaternion operator+() const noexcept
constexpr Quaternion()
1 + {0,0,0}で初期化する,
constexpr Quaternion(const Quaternion &q)=default
コピーコンストラクタ.
constexpr Quaternion operator-() const noexcept
constexpr float GetDistanceSquared(const Quaternion &q) const noexcept
他のクォータニオンとの距離の2乗を返す. クォータニオンを4次元ベクトルとみなし,ベクトルの距離の2乗を求める.
bool operator<(const Quaternion &q) const noexcept
constexpr Quaternion operator*(const Quaternion &q) const noexcept
Quaternion GetInverse() const
クォータニオンの逆数を返す. クォータニオンqの逆数q^-1は,qの共役をノルムで割ったもの. q^-1 = q* / |q|^2
std::string ToCsvString() const
クォータニオンをCsv形式の文字列に変換する.カンマ区切り. w, x, y, z の順にカンマ区切りで出力する.
bool operator!=(const Quaternion &q) const noexcept
constexpr Quaternion(const float w_, const float x_, const float y_, const float z_)
スカラー成分とベクトル成分を指定して初期化する. ノルムが1になるように代入すること, 使用は非推奨,MakeByAngleAxisを使うこと.
float w
スカラー成分.
constexpr float Dot(Quaternion other) const noexcept
クォータニオンの内積を返す. クォータニオンを4次元のベクトルとみなし,ベクトルの内積を求める.
3次元の位置ベクトルを表す構造体.
float x
ロボットの正面方向に正.
constexpr Vector3 Cross(const Vector3 &other) const noexcept
自分×引数 の外積の結果を返す.
float z
ロボットの上向きに正.
constexpr float Dot(const Vector3 &other) const noexcept
自分・引数 の内積の結果を返す.
float y
ロボットの左向きに正.