※この記事はQiitaからの引越し記事です。
物体の姿勢の表し方には以下の2種類があります。
このうちクオータニオンはオイラー角とは異なり、ある姿勢を一意に決めてしまうものなので、 オイラー角のように見た目の姿勢変化をそのまま値に反映することはできません。
本稿ではそんなクオータニオンの平均を取る手法について話します。
補足
「平均化」とは言わず、普通は「線形補間」と言います。
ただ、今回の目的が線形補間の中間地点を取得することなので、わかりやすさのために敢えて「平均化」と言ってます。
lerp() / slerp()
Unityで主に使われている手法で、2点間の異なるパラメータを[0〜1]の範囲で線形補間することができます。 詳しい話は以下参照
対数化による線形補間
これは前項のlerp()/slerp()にも使われてる気がする。。
クオータニオンの平均(Averaging Quaternions)
平均化されたクオータニオンは次のように表すことができます。
なお、クオータニオンの特徴で、回転行列 は直交行列(orthogonal matrix)となります。
Step 1 数式の簡略化
ここで、
となるので、
Step 2 魔法の力による簡略化
ここでは魔法の力を借りることで更なる簡略化を施します。 (魔法の力については最後の章で話します。ひとまず受け入れてクダサイ。)
ここでの、は以下の通り。
Step 3 座標空間の変換
は先程の式より、対称行列(symmetric matrix)であることがわかります。 (すべての要素が実数である場合、「実対称行列」と呼びます。)
よってに対角化を行い、元の数式に適用します。 が対称行列なので、対角化によって現れる行列は直交行列であり、その大きさは1となります。
ここで、により、数式の空間をからへと変換します。 のノルムが1であることと、行列が直交行列であることから、 この変換によってベクトルはベクトルへ、大きさは変わらずに、向きだけが変わったものとみなせます。
Step 4 固有値・固有ベクトル
ここで、 行列の固有値の中で、ある固有値が最も大きい値であるとき、 行列の固有ベクトルの、ある固有ベクトルも最大となります。
したがって、クオータニオンの平均値はとなることがわかりました。
補足
前項での説明の補足を行っていきます。 リクエストなどがあればコメントください。
魔法の力について
Step 2では「魔法の力」ということにして説明をごっそり省きました。 なぜなら、この部分の変換がかなりハードであるためです。。(ユルシテクダサイ)
この節ではこのとき何が行われていたのかを(ざっくり)説明していきます。
回転行列Q
クオータニオンのベクトルを次のように表すとします。
クオータニオンの回転行列はベクトルを使って次のように表します。
地獄の式変換
回転行列を展開し、上式をベクトルのみで表していきます。
・・・嘘です。やりません。 やろうとしましたが、途中で青ざめて挫折しました。
先人の知識によれば、ここを頑張って耐えしのぐことで以下の等式が得られるとのこと。 今回は先人の知識を「魔法の力」として利用させていただきました。感謝!
クオータニオンの線形補間に関する基本的な手法です。 クオータニオンの値を対数化した後、
線形代数
説明に出てきた内容です。
- 行列のノルム(Frobenius norm)
- 対角和(trace)
- 行列式(determinant)
- 交換法則
対角和と行列式には次のような交換法則が成り立ちます。
よって、対角行列に対して次のような変換が可能です。