GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
math_quaternion.cpp
[詳解]
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#include "math_quaternion.h"
9
10#include <sstream>
11
12#include "cassert_define.h"
13
14
15namespace designlab
16{
17
19{
20 // ノルムが0の場合は,(0,0,0,0)を返す.
21 const float norm = GetNorm();
22
23 if (norm == 0.f)
24 {
25 return { 0.f, 0.f, 0.f, 0.f };
26 }
27
28 return *this * (1.f / norm);
29}
30
31Quaternion Quaternion::MakeByAngleAxis(const float angle, const Vector3& axis)
32{
33 // オイラー角をクオータニオンに変換.
34
35 const float half_angle = angle * 0.5f;
36
37 return { cosf(half_angle),
38 Vector3{ axis.x, axis.y, axis.z }.GetNormalized() * sinf(half_angle) };
39}
40
41std::string Quaternion::ToString() const
42{
43 std::string str;
44 str += "( w: " + math_util::FloatingPointNumToString(w) +
47 ", z: " + math_util::FloatingPointNumToString(v.z) + " )";
48 return str;
49}
50
51std::string Quaternion::ToCsvString() const
52{
53 std::stringstream ss;
54 ss << *this;
55 return ss.str();
56}
57
58Quaternion SlerpQuaternion(const Quaternion& q1, const Quaternion& q2, const float t)
59{
60 assert(0 <= t && t <= 1); // tが 0 ~ 1 の間に収まっているか確認.
61
62 if (q1 == q2) { return q1; } // クォータニオンが等しい場合は,q1を返す.
63
64 // 球面線形補間を行う.
65 float dot = q1.Dot(q2); // 内積.
66
67 if (1.0f < dot)
68 {
69 // 内積が1より小さい場合は,1にする.
70 dot = 1.0f;
71 }
72 else if (dot < -1.0f)
73 {
74 // 内積が-1より大きい場合は,-1にする.
75 dot = -1.0f;
76 }
77
78 const float theta = acosf(dot); // 角度.
79
80 // 角度が0の場合は,q1を返す.
81 if (math_util::IsEqual(theta, 0.f)) { return q1; }
82
83 const float sin_theta = sinf(theta); // sin(θ)
84 const float sin_theta_inv = 1 / sin_theta; // 1 / sin(θ)
85
86 const float sin_t_theta = sinf(t * theta); // sin(tθ)
87 const float sin_1_t_theta = sinf((1 - t) * theta); // sin((1-t)θ)
88
89 // 補間されたクォータニオンを返す.
90 return sin_1_t_theta * sin_theta_inv * q1 + sin_t_theta * sin_theta_inv * q2;
91}
92
93} // namespace designlab
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
Quaternion SlerpQuaternion(const Quaternion &q1, const Quaternion &q2, const float t)
球面線形補間を行う.
クォータニオンを表す構造体.
Quaternion GetNormalized() const noexcept
正規化したクォータニオンを返す. クォータニオンの正規化とは,ノルムを1にすることを表す. クォータニオンqの正規化は,q / |q| で求められる.
std::string ToString() const
クォータニオンを文字列に変換する. w, x, y, z の順で出力する.
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
ベクトル成分.
std::string ToCsvString() const
クォータニオンをCsv形式の文字列に変換する.カンマ区切り. w, x, y, z の順にカンマ区切りで出力する.
float w
スカラー成分.
constexpr float Dot(Quaternion other) const noexcept
クォータニオンの内積を返す. クォータニオンを4次元のベクトルとみなし,ベクトルの内積を求める.
3次元の位置ベクトルを表す構造体.
float x
ロボットの正面方向に正.
float z
ロボットの上向きに正.
float y
ロボットの左向きに正.