回転の平均
概要
三次元空間における回転を平均化するという概念についてのメモ。
特に複数の回転クォータニオンがあって平均を取りたい場合。
色々な手法
まずstackoverflowのトピックを参照。
様々な手法が出てくる。
また、そもそも回転に平均値の概念はないという指摘も出てくる。
→回転集合との誤差を最小にする回転、という表現になるようだ。
行列計算によるもの
上記トピックで最も評価がついているのは、クォータニオン列を並べた4xN行列とその転置行列との積で生まれる4x4行列について
最大の固有値に紐づく固有ベクトルが求めるクォータニオンである、というものだ。
固有値と固有ベクトルを求める方法はいろいろある。
上記手法で得た4x4行列は対称なので、Jacobi法が適用できる。
Jacobi法については下記サイトが参考になる。
また、行列のサイズが4x4までなら解析的に解が出せるらしい。未調査。
(サイズ5からは数値解しかない、という記述をあちこちで見た)
英Wikipediaに3x3までの計算法が載っているが、
for 4×4 matrices the increasing complexity of the root formulas makes this approach less attractive.
ということだ。
固有値問題の解き方に依存した実装の面倒さがある。
私はJacobi法で試してみたが、クォータニオンの性質上か、対角成分が一定以上小さくならなくなるケースにハマることがあった。
さらに、私の理解が追い付いていないためか、この手法で得られたクォータニオンをInverseしないと期待した解にならなかった。
→実験で使ったUE4が左手系だからかも
補間によるもの
集めた回転を順番にSlerp補間していくというもの。
補間を適用する順番で結果が異なるが、平均化対象の回転それぞれが似たようなものであれば概ね問題ないと主張されている。
また、キャラクターアニメーションシステムにおいて複数の姿勢を加重ブレンドする場合も
適用順を意識しつつ重みづけして所望の動作を得るらしい。
平均化対象が2つならこの手法で問題ないだろう。
乗算によるもの
集めた回転を重みづけしつつ順番に乗算するというもの。
当然、これも乗算順で結果が異なる。
上記のgamedevのコメントによると、精度が不要な時は速度重視で乗算による方法を用いることもあるようだ。
和算によるもの
集めた回転を和算して最後に正規化するというもの。
この方法はComputer Graphics Gems JP 2012 のパーティクルIK実装例でも用いられている。
概ねそれらしい結果が出るが、特定のケースではうまくいかない。
わかりやすい例は「Yaw回転179°」と「Yaw回転-179°」の平均はいくらか、という場合だ。
「Yaw回転±180°」を期待するが、この方法だと「Yaw回転0°」の解が出てしまう。(遠回りする方の解になる、というべきか)
他
対数クォータニオンに変換すると、複数の回転の合計を容易に扱えるらしい。
「姿勢推定 クォータニオン」で検索すると、衛星の姿勢推定に関する日本語の論文が出てくる。
現状のまとめ
私がこの調査を行った目的は、
マルチエフェクタFABRIKの実装においてsub-baseとなる関節の向きが期待と異なる問題に遭遇したのがきっかけだ。
クォータニオンの和算と正規化で回転を推定していた為ということはわかったので、
どのようなアプローチが今風なのかを調査した。
関節の回転における問題では、回転拘束がついていることがほとんどであるので、
補間によるものを採用するのがよいだろうと結論づけている。(今のところ)
識者の方へ
間違った情報を書いてしまっている可能性が高いので、お気づきの点があればご指摘ください。
以上