プロが教えるわが家の防犯対策術!

皆様、いつもお世話になっております。
任意軸回転行列関係でひとつ疑問が出たので質問させていただきます。

3D物理シミュレータで物体の回転を扱うときに出た疑問です。
「アクセル」という行列に、単位行列を初めとして、さまざまな任意軸回転行列を、左から掛けていきます。
これが終わると「アクセル」はある回転行列になるはずです。
次に、問題があります。「ベロシティ」という行列に、「アクセル」という回転行列を、左からそのまま掛けるのではなく、回転量をちょっと少なくした、弱い回転を、しかしながら回転軸は同じものを、掛けたいのです。

--
・まず思いついた解決策:
回転角と回転軸を保持しておいて、ベロシティに「回転軸」と「デルタ×回転角」を掛ける、という方法。
=>しかしアクセルの時点で、行列を左から掛けていきたいので、この過程で回転角と回転軸を更新し続ける手法がわかりません。そもそも存在するのでしょうか。

・次に思いついた方法:
アクセルで左から任意軸回転行列をかけていった完成品は、これもまた任意軸回転行列のはずですから、この完成した行列から回転軸と回転角を逆算して、ベロシティに掛ける行列を「回転軸」と「デルタ×回転角」から再構成する、という方法。
=>任意軸回転行列から回転角と回転軸を逆算する方法がわかりません。

・次に思いついた方法:
任意軸回転行列から角度と軸を逆算しなくとも、任意軸回転行列に、何かしら手を加えると、回転角度に定数を掛け、回転量を調節することができる。
=>どんな方法があるのだろうか
--

これらの推測はしましたが、どれも解答にたどり着けませんでした。
どうかよろしくお願い致します。
不明な点がございましたら随時補足いたします。

A 回答 (5件)

まず、行列は回転は表現できても、回転量は表現できません。



たとえば、x軸を中心に2π回転したことを表す行列というのは単位行列になります。

そこから回転量をちょっと少なくしても単位行列から変化しないことは理解できると思います。

つまり、必然的に回転量={回転軸+角度}という形で管理しなければならないということです。

回転軸+角度をを行列に反映する方法はわかると思います。

あとは回転量の合成ですが、それにはクォータニオンを利用します。

クォータニオンには下記の特徴があります。

・回転軸と角度からクォータニオンを作ることができる。
・クォータニオンから回転軸と角度を得ることができる。
・2つのクォータニオン同士の積は、2つの回転量を合成した回転量を表す。

上記を利用すると、回転量の合成が出来ることがわかると思います。

注意が必要なのは、クォータニオンも行列と同様に

ある軸を中心に2πの回転を表すクォータニオン == ある軸を中心に0の回転を表すクォータニオン

ということです。

これの対策としては、回転量の合成を行う前にスケーリングして正規化し、合成後の回転量に逆の変換を行うことで正しい結果を得ることが出来ます。

この回答への補足

お礼の「任意軸回転行列同士の積は必ずしも任意軸回転行列ではない。なぜなら任意の姿勢に持っていくためには回転は最低でも二度必要だからだ。」
やっぱりこれ間違ってますよね。一度でいけますよね。XYZではなく任意軸ならば。
角度と軸を抽出するならクォータニオンがよいということですよね。失礼いたしました。

補足日時:2013/06/14 08:16
    • good
    • 0
この回答へのお礼

qwertfk様、わかりやすい解説ありがとうございます。
クォータニオンならば回転軸と角を復元できるのですね。
> 回転量の合成を行う前にスケーリングして正規化し、合成後の回転量に逆の変換を行うことで正しい結果を得ることが出来ます。

こちらも参考にさせていただきます。

自分の質問について間違いがありました。
・任意軸回転行列同士の積は必ずしも任意軸回転行列ではない。なぜなら任意の姿勢に持っていくためには回転は最低でも二度必要だからだ。
という点です。
よって(クォータニオンではなく、任意軸回転行列の場合)出来上がった行列から角度と軸を1つだけ抽出することはできないという結論に至りました。
1日悩んだ結果、この解法として、自分がやりたいのは積としての回転行列の回転量にdtを掛けるということだったので、あらかじめ回転量にdtを掛けた回転行列達の積をとることを思いつきました。

これが予期する動作を見せるか全く検討がつきません。
将来的にはこちらでご回答いただいたクォータニオンやスケーリングのお話を参考にさせていただくことになると思います。
ありがとうございました。

お礼日時:2013/06/14 08:13

本題とは外れたところからいきますが, 純粋に回転角を記憶しておくのでなければ「デルタ×回転角」という方法はやめた方がいいと思います. 回転を行列や四元数のような形で記憶していると 360° の倍数の情報が消えてしまうので, うまく計算できない可能性があります.



四元数からは回転角や回転軸の情報も (わりと簡単に) 取り出せるんでできないこともないですが, 上に書いたように「360° の倍数の情報」は消えてしまいます.
    • good
    • 0
この回答へのお礼

そうなんですよね。
「半分回す」を行うとき、時計回りか反時計回りかで半分掛けた回転先が変わるので気づきました。

お礼日時:2013/06/14 07:02

アフィン変換を用いるのが分かりやすいように思います。


例えば、
http://imagingsolution.blog107.fc2.com/blog-entr …
のあたりを参考に

まず、回転軸が特定の軸(例えばz軸)になるように回転させます。任意回転軸上の2点の座標を基準に考えると理解しやすいです。

(1)Z軸上に回転軸が重なるように移動
X軸周りに回転→Y軸周りに回転(ここまででZ軸と平行になるように)→平行移動(z軸上に)
(2)z軸を中心に回転
(3)先の(1)の逆でもとにもどす
平行移動→Y軸周りに回転→X軸周りに回転

以上を4行4列の変換行列だけを計算すれば良いので計算量は多くはありません。軸周りの回転を変えるときには(2)だけを変えることで可能です。

二次元の例ですが、以前回答したものです(プログラムも載せています)
http://okwave.jp/qa/q8038779.html

また物質の回転軸が固定されている(独楽)のような場合や、回転中心が固定されているなどの場合は(1)からではなく(2)から始める方が楽なことがあります。その例
http://yahootv.okwave.jp/qa7872743.html
    • good
    • 0
この回答へのお礼

回転を行う際の1メソッドということでしょうか?
ありがとうございます。

お礼日時:2013/06/14 07:06

3次元空間中の回転については, 行列を使うほかに「四元数」を使う方法が考えられます.

この回答への補足

クォータニオンを勉強すればこの問題は解決されるでしょうか?

補足日時:2013/06/13 16:55
    • good
    • 0

ど~しても行列じゃないとだめですか?

この回答への補足

どういう代替案をお持ちか検討がつかないので「行列でなくてもよいですよ」と申し上げておきます。
迅速なお返事ありがとうございます。助かります。。

補足日時:2013/06/13 15:37
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!