永井 忠一 2024.11.30
クォータニオン \( q(t) \) の時間微分\[ \begin{align} \frac{d q(t)}{dt} = \dot{q}(t) &= \lim_{h\to 0}\frac{q(t+h) - q(t)}{h} \\ & = \lim_{h\to 0}\frac{\begin{pmatrix} n_x\sin\frac{\dot\theta h}{2} \\ n_y\sin\frac{\dot\theta h}{2} \\ n_z\sin\frac{\dot\theta h}{2} \\ \cos\frac{\dot\theta h}{2} \end{pmatrix}q(t) - q(t)}{h} \\ & = \lim_{h\to 0}\frac{\begin{pmatrix} n_x\sin\frac{\dot\theta h}{2} \\ n_y\sin\frac{\dot\theta h}{2} \\ n_z\sin\frac{\dot\theta h}{2} \\ \cos\frac{\dot\theta h}{2} \end{pmatrix}q(t) - \begin{pmatrix} 0 \\ 0 \\ 0 \\ 1 \end{pmatrix}q(t)}{h} \\ & = \lim_{h\to 0}\frac{\left(\begin{pmatrix} n_x\sin\frac{\dot\theta h}{2} \\ n_y\sin\frac{\dot\theta h}{2} \\ n_z\sin\frac{\dot\theta h}{2} \\ \cos\frac{\dot\theta h}{2} \end{pmatrix} - \begin{pmatrix} 0 \\ 0 \\ 0 \\ 1 \end{pmatrix}\right)q(t)}{h} \\ & = \lim_{h\to 0}\frac{\begin{pmatrix} n_x\sin\frac{\dot\theta h}{2} \\ n_y\sin\frac{\dot\theta h}{2} \\ n_z\sin\frac{\dot\theta h}{2} \\ \cos\left(\frac{\dot\theta h}{2}\right) - 1 \end{pmatrix}q(t)}{h} \\ & = \lim_{h\to 0}\begin{pmatrix} \frac{n_x\sin\frac{\dot\theta h}{2}}{h} \\ \frac{n_y\sin\frac{\dot\theta h}{2}}{h} \\ \frac{n_z\sin\frac{\dot\theta h}{2}}{h} \\ \frac{\cos\left(\frac{\dot\theta h}{2}\right) - 1}{h} \end{pmatrix}q(t) \\ & = \begin{pmatrix} \lim\limits_{h\to 0}\frac{n_x\sin\frac{\dot\theta h}{2}}{h} \\ \lim\limits_{h\to 0}\frac{n_y\sin\frac{\dot\theta h}{2}}{h} \\ \lim\limits_{h\to 0}\frac{n_z\sin\frac{\dot\theta h}{2}}{h} \\ \lim\limits_{h\to 0}\frac{\cos\left(\frac{\dot\theta h}{2}\right) - 1}{h} \end{pmatrix}q(t) \\ &= \begin{pmatrix} \frac{n_x\dot\theta}{2} \\ \frac{n_y\dot\theta}{2} \\ \frac{n_z\dot\theta}{2} \\ 0 \end{pmatrix}q(t) \\ &= \frac{1}{2}\begin{pmatrix} n_x\dot\theta \\ n_y\dot\theta \\ n_z\dot\theta \\ 0 \end{pmatrix}q(t) = \frac{1}{2}\begin{pmatrix} \omega_x \\ \omega_y \\ \omega_z \\ 0 \end{pmatrix}q(t) \end{align} \]
limit の計算(Maxima による記号計算)
Maxima | |
---|---|
|
\[ \begin{pmatrix} \lim\limits_{h\to 0}\frac{n_x\sin\frac{\dot\theta h}{2}}{h} \\ \lim\limits_{h\to 0}\frac{n_y\sin\frac{\dot\theta h}{2}}{h} \\ \lim\limits_{h\to 0}\frac{n_z\sin\frac{\dot\theta h}{2}}{h} \\ \lim\limits_{h\to 0}\frac{\cos\left(\frac{\dot\theta h}{2}\right) - 1}{h} \end{pmatrix} = \begin{pmatrix} \frac{n_x\dot\theta}{2} \\ \frac{n_y\dot\theta}{2} \\ \frac{n_z\dot\theta}{2} \\ 0 \end{pmatrix} \] |
《天下り》\[ q(t) = \int \dot q(t)\, dt = \int w\, dt + \left(\int x\, dt\right)i + \left(\int y\, dt\right)j + \left(\int z\, dt\right)k \]
離散の式\[ q(t) = \sum \dot q(t)\varDelta t = \sum w\varDelta t + \left(\sum x\varDelta t\right)i + \left(\sum y\varDelta t\right)j + \left(\sum z\varDelta t\right)k \]
クォータニオンは数。次の式で書かれる\[ q = w + x i + y j + z k \]
また、\[ q = (w, x, y, z) \]という形でも書かれる。\( w \) の位置には、流儀がある\[ q = (x, y, z, w) \]
縦に書くこともある\[ q = \left(\begin{array}{c} w \\ x \\ y \\ z \end{array}\right), \quad q = \left(\begin{array}{c} x \\ y \\ z \\ w \end{array}\right) \]
呼び方:
ライブラリ、パッケージのインストール
Linux apt |
---|
|
ドキュメント
クォータニオンの和
C/C++ 言語 | |
---|---|
OpenGL Mathematics (GLM) | Bullet LinearMath |
|
|
Octave の quaternion パッケージを利用して検算
Octave |
---|
|
ゼロ・クォータニオン(和の単位元)\( (0, 0, 0, 0) \)
C/C++ 言語 | |
---|---|
GLM | Bullet LinearMath |
|
|
Octave | |
|
クォータニオンの符号反転。単項のマイナス(和の逆元)
C/C++ 言語 | |
---|---|
GLM | Bullet LinearMath |
|
|
Octave | |
|
クォータニオンの積
C/C++ 言語 | |
---|---|
GLM | Bullet LinearMath |
|
|
Octave | |
|
(※クォータニオンの積は非可換)
恒等クォータニオン(クォータニオンの積の単位元)\( (1, 0, 0, 0) \)
C/C++ 言語 | |
---|---|
GLM | Bullet LinearMath |
|
|
Octave | |
|
また、identity quaternion を得るための「quat_identity() 関数、getIdentity() メソッド」がある
glm::quat_identity<glm::quat::value_type, glm::highp>()
btQuaternion::getIdentity()
(※GLM では「Experimental extensions」扱いなので、『glm/gtx/quaternion.hpp』をインクルードする必要がある)
クォータニオンのノルム\[ \lvert q \rvert = \sqrt{w^2 + x^2 + y^2 + z^2} \]
C/C++ 言語 | |
---|---|
GLM | Bullet LinearMath |
|
|
Octave | |
|
また、GLM と Bullet LinearMath ともに、\( \lvert q \rvert^2\) を求める「length2() 関数、メソッド」がある
(※GLM で length2() 関数は「Experimental extensions」扱いなので、使用するためには『glm/gtx/quaternion.hpp』をインクルードする必要がある)
単位クォータニオン\[ w^2 + x^2 + y^2 + z^2 = 1 \](ノルムが1のクォータニオン)
クォータニオンの正規化
C/C++ 言語 | |
---|---|
GLM | Bullet LinearMath |
|
|
Octave | |
|
(Bullet LinearMath には、イミュータブル版の「normalized() メソッド」も用意されている)
共役クォータニオン\[ q^* = w - x i - y j - z k \](虚部の符号を反転したもの)
C/C++ 言語 | |
---|---|
GLM | Bullet LinearMath |
|
|
Octave | |
|
(※Bullet LinearMath では、「inverse() メソッド」は共役クォータニオンを求める)
逆クォータニオン。クォータニオンの逆数(クォータニオンの積の逆元)\[ q^{-1} = \frac{q^*}{\lvert q \rvert^2} \]
C/C++ 言語 | |
---|---|
GLM | Bullet LinearMath |
|
|
Octave | |
|
(逆クォータニオンを求めるメソッドが用意されていない場合には、\( {q^*}/{\lvert q \rvert^2} \) として求める)
もし、\( q \) が単位クォータニオンならば、\( \lvert q \rvert = 1 \) より\[ q^{-1} = q^* \]となる
C/C++ 言語 | |
---|---|
GLM | Bullet LinearMath |
|
|
Octave | |
|
ゼロ・クォータニオンとの積
C/C++ 言語 | |
---|---|
GLM | Bullet LinearMath |
|
|
Octave | |
|
(零因子は存在しない)
《→ 以前のページ》
単位ベクトル \( \vec n \) が表す任意の回転軸に関する \( \theta \) の回転を表すクォータニオンは\[ q = \left(cos\frac{\theta}{2},\, \vec n\sin\frac{\theta}{2}\right) \]のように書ける(「\( {\theta}/{2} \)」は、『half angle』と呼ばれる)
クォータニオンを使って位置ベクトルを回転\[ v^\prime = qvq^* \]ここで、\( v \) は位置ベクトル \( \vec v \) を純粋クォータニオン \( v = (0,\, \vec v) \) で表現したもの(実部が0のクォータニオンを純粋クォータニオン。もしくは、純虚クォータニオン)
(\( q^* \) は \( q \) の共役クォータニオン)
演算の結果 \( v^\prime \) は実部が必ず0になり(純粋クォータニオンになる)、虚部には変換後の3次元座標(位置ベクトル)が格納される
回転軸と回転角を指定して、回転を表現するクォータニオンを作成
C/C++ 言語 | |
---|---|
GLM | Bullet LinearMath |
|
|
Octave | |
|
(Bullet LinearMath では、btQuaternion クラスのコンストラクターで、回転軸のベクトルの正規化を行っている)
回転を表すクォータニオンのノルムは1
C/C++ 言語 | |
---|---|
GLM | Bullet LinearMath |
|
|
Octave | |
|
クォータニオンの内積
C/C++ 言語 | |
---|---|
GLM | Bullet LinearMath |
|
|
Octave | |
|
(Octave の dot() 関数はクォータニオンの内積を計算できない。Octave で「'」演算子は複素共役転置を求める演算子でクォータニオンに対しても使用できるため、「'」演算子を利用して内積を計算している。また、「.w」は実部へのアクセッサー)
(※クォータニオンの内積が1に近ければ同じ回転(姿勢)をしているが、クォータニオンには二価性があるため、fabs() 関数で絶対値をとってから内積の結果を評価する)
クォータニオンの二価性
C/C++ 言語 | |
---|---|
GLM | Bullet LinearMath |
|
|
Octave | |
|
(Octave の表示では、浮動小数点数の演算誤差が見えているが、非常に小さい値になっているので無視できる)
(※回転(姿勢)を表すクォータニオンは、初期の 0° のものと、360° 回転したものとでは表現が異なっている。720° 回転して(2回転して)もとの表現に戻る)
回転行列とクォータニオンとの相互変換
C/C++ 言語 | |
---|---|
GLM | Bullet LinearMath |
|
|
Octave | |
|
(Bullet LinearMath には、btMatrix3x3 クラスのモディファイアとして「setRotation() メソッド」も用意されている)
(Octave の quaternion パッケージには、クォータニオンを回転行列へ変換する関数は用意されていない)
(※クォータニオンを回転行列へ変換することで、クォータニオンの二価性は消失している)
回転行列とクォータニオンによる回転とが一致していることを確認
C/C++ 言語 | |
---|---|
GLM | Bullet LinearMath |
|
|
《以前のページ → X, Y, Z 軸まわりの回転行列》
角速度ベクトルがグローバル座標系で表現される場合:\[ \frac{d q}{dt} = \frac{1}{2}\omega q \]ここで、角速度は、純粋クォータニオンで \( \omega = (0, \omega_x, \omega_y, \omega_z) = (0,\, \vec\omega) \) と書かれている
角速度ベクトルが回転する物体のローカル座標系で表現されている場合:\[ \frac{d q}{dt} = \frac{1}{2}q\omega \]
© 2024 Tadakazu Nagai