はじめに
こちらの記事で「2次元の剛体変換を任意点回りの回転に変換」ができたので、
3次元でもできるかやってみました。
結論できません。できるとしたら、かなり限定的な条件を満たすときです。
まあ、でもせっかく計算したので、そのログとして本記事を書きます。
【不可能】3次元の剛体変換を任意点回りの回転に変換することは不可能【不可能】
剛体変換行列を とします。
回転行列を 、平行移動行列を とします。
任意点周りの行列は と書けるので、以下が成り立ちます。
式 の左辺を計算します。
式 より以下が成り立ちます。
回転行列 の回転軸を表す単位ベクトル と、回転角 を使って以下のように書けます。
(回転軸と回転角は回転行列を四元数に直せば簡単に求まります。)
式 は式 より、以下のように書けます。
式 の左辺の行列を とします。
この の行列式を計算します。(SymPyを使って計算しました。本記事の下の方にSymPyを使ったプログラムを書いています。)
以上より、3次元の剛体変換は任意点回りの回転に変換できないことが分かりました。
少しだけ考察
でも、2次元の剛体変換は任意点回りの回転に変換できるんだからどうにかならないでしょうか?
ここからは推測なのですが、回転後の平行移動ベクトルが回転軸と垂直なら、その剛体変換は実質2次元なので、うまくいきそうです。
ですが、それを考えることはあまり意味がなさそうなので、ここまでとしておきます。
SymPyをつかった行列式の計算
手計算は大変なので、SymPyを使って計算しました。
from sympy.algebras.quaternion import Quaternion from sympy import * init_printing() var('r_0,r_1,r_2,r_3,r_4,r_5,r_6,r_7,r_8,theta,a_x,a_y,a_z') r_0 = cos(theta) + a_x ** 2 * (1 - cos(theta)) r_1 = a_x * a_y * (1 - cos(theta)) + a_z * sin(theta) r_2 = a_x * a_z * (1 - cos(theta)) - a_y * sin(theta) r_3 = a_x * a_y * (1 - cos(theta)) - a_z * sin(theta) r_4 = cos(theta) + a_y ** 2 * (1 - cos(theta)) r_5 = a_y * a_z * (1 - cos(theta)) + a_x * sin(theta) r_6 = a_x * a_z * (1 - cos(theta)) + a_y * sin(theta) r_7 = a_y * a_z * (1 - cos(theta)) - a_x * sin(theta) r_8 = cos(theta) + a_z ** 2 * (1 - cos(theta)) R = Matrix([ [r_0, r_3, r_6 ], [r_1, r_4, r_7 ], [r_2, r_5, r_8 ], ]) I = Matrix([ [1, 0, 0 ], [0, 1, 0 ], [0, 0, 1 ], ]) M = I - R M_det = M.det() M_det = factor(M_det) display(M_det) display(M)
プログラムの実行結果
最後に
できないことがちゃんと示せるなんて線形代数は偉大ですねー