traP Member's Blog

合同変換及び運動について【新歓ブログリレー2017 24日目】

hatasa-y
このエントリーをはてなブックマークに追加

こんにちは。理学院数学系2年のhatasa-yです。

traPでは最近までtiteQuestのプログラムを担当させていただいていまして完成となりました。

前回書いた記事は自分では完全にもの足りない結果と感じているので、また同じような内容で書こうと思います。

というわけで線形代数についてなるべく新入生にも分かるように書こうと思います。(ほんまか)

合同変換

合同変換の定義は、空間の点の変換で、二点間の距離を変えないもののことです。(ここでは、空間はユークリッド平面またはユークリッド空間のことを指します)

下の図のようにPQをP’Q’と変換させるのは合同変換となります。

これより先は空間座標について考えますが、まず線形変換の定義について説明します。

線形変換

線形写像

定義

K上の線型空間VからK 上の線型空間V’への写像Tが次の二条件を満たすとき、TをVからV’への線型写像と言う。

T(x+y) = Tx + Ty , \quad T(ax) = aTx

線形変換

定義

VからV自身への線型写像をVの線型変換と言う。

補足

K上の線型空間Vが何のことか分からない場合は線形代数の教科書を見てください。

今回議論しようとしている\mathbb{R}^2\mathbb{R}^3\mathbb{R}上の線型空間です。

写像T \colon \mathbb{R}^3 \to \mathbb{R}^3 が線形写像であれば、写像Tは線形変換となります。

空間の合同変換

まず空間について原点OがO自身に移るような合同変換T_0について考えます。

T_0が線形変換であることを示します。

まず3点O,P,Qが一直線上にあり、2点P,Qを合同変換させて点P’,Q’に移ったときについて考えます。

\vec{OP}=x, \vec{OQ}=cx とおくと

\vec{OP'}=T_0x, \vec{OQ'}=T_0(cx)であります。

OQ=OP+PQであり原点OはO自身に移ることでOQ’=OP’+P’Q’が成り立つので、

O,P’,Q’が一直線上にあることを示しています。

よって\lvert \vec{OQ'} \rvert / \lvert \vec{OP'} \rvert = \lvert \vec{OQ} \rvert / \lvert \vec{OP} \rvert = cより

 

\vec{OQ'}=c\vec{OP'}=cT_oxであるので

T_0(cx)=cT_0xが成り立ちます。

 

次に4点O,P,Q,Rが\vec{OR}=\vec{OP}+\vec{OQ} を満たすものについて考えます。

\vec{OP}=x, \vec{OQ}=yとおくと

\vec{OR}=x+y, \vec{OP'}=T_0x, \vec{OQ'}=T_0y, \vec{OR'}=T_0(x+y)

三辺の長さを考えると、三角形は合同な三角形に移るので

 

\vec{OR'}=\vec{OP'}+\vec{OQ'}=T_0x+T_0y

よってT_0(x+y)=T_0x+T_0yが成り立ちます。

 

これより合同変換T_0は線形変換となります。

また任意のxに対して \lVert T_0 x \rVert = \lVert x \rVertが成り立ちます。

線形写像と行列表示

次の命題が成立する。(証明はしない)

命題

写像f:\mathbb{R}^n \to \mathbb{R}^m に対し、次の同値関係が成立する。

fが線形写像\Leftrightarrow \exists 1 A \in M_{mn} (\mathbb{R}) \forall x \in \mathbb{R}^n s.t. f(x)= Ax

補足

\exists 1は存在して唯一という意味で、M_{mn}はm×n型の行列です。

私が言いたいこと

これより先ほどのT_0は線形変換(写像)であったので3×3型の行列Aを用いて

T_0x=Axと表すことができる。

また\lVert A x \rVert=\lVert x \rVert が成立する。

直交行列

定義

n×n実行列Aが、{}^t AA=A{}^tA=Eを満たすとき、Aを直交行列という。

次の命題が成り立つ。(証明はしない)

命題

n×n実行列Aについて次は同値である。

  1. {}^t AA=A{}^tA=E(定義)
  2. {}^t AA=E
  3. A{}^tA=E
  4. Aの列ベクトルa_1, \cdots , a_n \in \mathbb{R}^n\mathbb{R}^n の実標準内積に関して正規直交基底
  5. Aの行ベクトルの転置b_1, \cdots , b_n \in \mathbb{R}^n\mathbb{R}^n の実標準内積に関して正規直交基底
  6. 線形写像\phi \colon \mathbb{R}^n \to \mathbb{R}^n ; x \mapsto Axは実標準内積について\forall x, y \in \mathbb{R}^n [( \phi (x) , \phi(y) )=(x,y)]
  7. 線形写像\phi \colon \mathbb{R}^n \to \mathbb{R}^n ; x \mapsto Axは実標準内積について\forall x \in \mathbb{R}^n [\lVert \phi (x) \rVert = \lVert x \rVert]

私が言いたいこと

\lVert A x \rVert= \lVert x \rVertが成立するので、上の7番が成立することになる。

これより行列Aは直交行列となる。

空間の合同変換(続き)

平行移動

さて今までは原点OがO自身に移るような合同変換T_0について考えてきました。

まず初めに平行移動T_1を考えてみます。

原点OがO’に移るとしてa=\vec{OO'}とおくと

T_1x = x + aが成り立つ。

一般の合同変換

合同変換Tについて考えます。

原点OがO’に移るとしてa=\vec{OO'}とおく。

T^{-1}_1x=x-aとおくと、これは平行移動T_1の逆変換となる。

T_0=T^{-1} \circ TとおくとT_0は合同変換であり、原点OをO自身に移すので

T_0x = Ax となり

T x = (T_1 \circ T_0 ) x = T_1 (Ax) = Ax+aとなります。

非斉次位置ベクトル

ここで次のベクトル\tilde{x} = \begin{pmatrix} x \\ 1 \end{pmatrix}及び行列\tilde{A} = \begin{pmatrix} A & a \\ {}^t o & 1 \end{pmatrix}を考える。(\tilde{x}を非斉次ベクトルと言う)

このとき\tilde{A} \tilde{x} = \begin{pmatrix} A & a \\ {}^t o & 1 \end{pmatrix} \begin{pmatrix} x \\ 1 \end{pmatrix}=\begin{pmatrix} Ax+a \\ 1 \end{pmatrix}

定理

以上のことをまとめると次の定理が言える。

空間の合同変換は、点の非斉次位置ベクトル\tilde{x}の変換と考えることができ、それは、\tilde{x}に次の行列\tilde{A}を左からかけることによって得られる。

\tilde{A} = \begin{pmatrix} A & a \\ {}^t o & 1 \end{pmatrix}

ただしAは三次(平面の場合:二次)直交行列でaは原点OがO’へと移る位置ベクトルである。

運動

合同変換Tが、図形を裏返しにしないとき、Tを運動という。

次の定理が成り立つ。(証明及び詳しい説明はしないことにする)

定理

合同変換Tが運動であるのは、T_0が回転である場合である。T_0が回転であるためには、行列Aの行列式が1であることが必要十分条件である。

補足

\begin{pmatrix} a_{11} & a_{12} \\ a_{21} & a_{22} \end{pmatrix} の行列式はa_{11}a_{22} - a_{12}a_{21}

\begin{pmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{pmatrix} の行列式はa_{11}a_{22}a_{33}+a_{12}a_{23}a_{31} + a_{13}a_{21}a_{32} - a_{13}a_{22}a_{31}-a_{12}a_{21}a_{33}-a_{11}a_{23}a_{32}

平面の運動

2×2行列Aが直交行列でかつ行列式が1となるものは \theta を用いて

A = \begin{pmatrix} \cos \theta & -\sin \theta \\ \sin \theta & \cos \theta \end{pmatrix}として表すことができるので(証明は練習問題とする)

\tilde{A} = \begin{pmatrix} \cos \theta & - \sin \theta & a \\ \sin \theta & \cos \theta & b \\ 0 & 0 & 1 \end{pmatrix}となる。

幾何学的に関しては高校の数学でやったと思うのでここでは説明は省きます。

空間の運動

オイラー角

3×3行列でAが直交行列でかつ行列式が1となるものは\psi, \theta, \phiを用いて

A= \begin{pmatrix} - \cos \theta \sin \phi \sin \psi + \cos \phi \cos \psi & - \cos \theta \sin \phi \cos \psi - \cos \phi \sin \psi & \sin \theta \sin \phi \\ \cos \theta \cos \phi \sin \psi + \sin \phi \cos \psi & \cos \theta \cos \phi \cos \psi - \sin \phi \sin \psi & -\sin \theta \cos \phi \\ \sin \theta \sin \psi & \sin \theta \cos \psi & \cos \theta \end{pmatrix}となります。

(証明には直交行列の固有値・固有ベクトル及び対角化の知識を持ってることが望ましい)

この\psi , \theta , \phiをオイラー角といいます。幾何学的には下の図のようになります。

変換前の座標軸をX,Y,Zとし、変換後の座標軸をX’,Y’,Z’とすると\thetaはZ軸とZ’軸とのなす角になり、\psiはZ軸,Z’軸を含む平面とX軸,Y軸を含む平面との交線ONがX軸とのなす角になります。また\phiはONがX’とのなす角になります。

ここでx軸のまわりの角\thetaの回転をX_{\theta}とし、z軸のまわりの角\phi , \psiの回転をそれぞれZ_{\phi}, Z_{\psi}とすると、

X_{\theta} = \begin{pmatrix} 1 & 0 & 0 \\ 0 & \cos \theta & - \sin \theta \\ 0 & \sin \theta & \cos \theta \end{pmatrix}, Z_{\phi} = \begin{pmatrix} \cos \phi & - \sin \phi & 0 \\ \sin \phi & \cos \phi & 0 \\ 0 & 0 & 1 \end{pmatrix}, Z_{\psi} = \begin{pmatrix} \cos \psi & - \sin \psi & 0 \\ \sin \psi & \cos \psi & 0 \\ 0 & 0 & 1 \end{pmatrix}であり(参考:平面の運動)

A = Z_{\phi} X_{\theta} Z_{\psi} となります。(右辺を計算すれば上の式と一致します)

これよりA'= \begin{pmatrix} Z_{\phi} X_{\theta} Z_{\psi} & a \\ {}^t o & 1 \end{pmatrix} となります。

 

以上より平面の運動および、空間の運動について行列で表すことが出来ました。パチパチ

 

 

 

しかし

空間の運動の行列表示難しくないですか?

私はこれを理解するのにかなり時間がかかりました。(私が馬鹿なだけですごめんなさい)

オイラー角は歳差運動を扱うには便利なものです。しかしそれ以外の回転だと難しくて(できないわけではない)、実際にプログラムでもめんどくさいです。その理由にはいくつかあって

  1. オイラー角の視覚化が難しい
  2. 思うような回転をするのに計算がいる
  3. 3つ行列の積の計算が大変
  4. Z_{\phi}, X_{\theta}, Z_{\psi}の計算が可換ではない

という訳で、プログラムではあんまり使いません。これよりも便利な回転があってプログラムではよくこちらの方を使います。

ロドリゲスの公式

オイラー角では3つの角を使って回転させるのに対して、ロドリゲスの公式は軸と軸のまわりの角度を使って回転をさせます。(ここは前回も書いたので同じような説明となります)

このような図を考えます。

ベクトル\mathbf{r}を回転軸ベクトル\mathbf{n}(ただし\lVert \mathbf{n} \rVert = 1)の回りに角\theta回転させたベクトルを\mathbf{r'}とし、\vec{OP}=\mathbf{r}, \vec{OQ}=\mathbf{r'}とします。

\mathbf{r'}=\vec{OM}+\vec{MT}+\vec{TQ}であるので

\mathbf{r'}=\mathbf{n}(\mathbf{n}, \mathbf{r})+(\mathbf{r}-\mathbf{n}(\mathbf{n}, \mathbf{r})) \cos \theta - (\mathbf{r} \times \mathbf{n}) \sin \thetaとなり

\mathbf{r'}=\mathbf{r} \cos \theta +\mathbf{n}(\mathbf{n}, \mathbf{r})(1-\cos \theta) - (\mathbf{r} \times \mathbf{n}) \sin \theta

\mathbf{r'}=\begin{pmatrix} x' \\ y'\\ z' \end{pmatrix}, \mathbf{r}=\begin{pmatrix} x \\ y \\ z \end{pmatrix}, \mathbf{n}=\begin{pmatrix} n_1 \\ n_2 \\ n_3 \end{pmatrix}(ただし n_1^2+n_2^2+n_3^2=1)としてこれを計算すると、次のようになります。

\begin{pmatrix} x' \\ y' \\ z' \end{pmatrix} = \begin{pmatrix} \cos \theta + n_1^2(1- \cos \theta ) & n_1 n_2 (1- \cos \theta ) - n_3 \sin \theta & n_1 n_3 (1- \cos \theta ) + n_2 \sin \theta \\ n_2 n_1 ( 1- \cos \theta) + n_3 \sin \theta & \cos \theta + n_2^2 (1- \cos \theta) & n_2 n_3 (1- \cos \theta ) -n_1 \sin \theta \\ n_3 n_1 (1- \cos \theta ) -n_2 \sin \theta & n_3 n_2 (1- \cos \theta ) + n_1 \sin \theta & \cos \theta + n_3^2 (1- \cos \theta ) \end{pmatrix} \begin{pmatrix} x \\ y \\ z \end{pmatrix}

これより行列\begin{pmatrix} \cos \theta + n_1^2(1- \cos \theta ) & n_1 n_2 (1- \cos \theta ) - n_3 \sin \theta & n_1 n_3 (1- \cos \theta ) + n_2 \sin \theta \\ n_2 n_1 ( 1- \cos \theta) + n_3 \sin \theta & \cos \theta + n_2^2 (1- \cos \theta) & n_2 n_3 (1- \cos \theta ) -n_1 \sin \theta \\ n_3 n_1 (1- \cos \theta ) -n_2 \sin \theta & n_3 n_2 (1- \cos \theta ) + n_1 \sin \theta & \cos \theta + n_3^2 (1- \cos \theta ) \end{pmatrix}を使えば任意軸回転をすることができます。

これはオイラー角よりも視覚化が回転で行列計算も(簡単ではないけど)難しい訳ではなくなりました。

応用

理論ばかりだとつまらないのでロドリゲスの公式の応用として、@sobaya007のshaderの作品を紹介しようと思います。(画像をクリックしてください)

見れば分かるように「ホモ」が回転しているわけですがプログラムの一部を紹介しようと思います。

vec3 eye = vec3(0, 0, 500.);
vec3 xvec = vec3(1., 0, 0);
vec3 yvec = vec3(0, 1., 0);
vec3 n = normalize(vec3(1., 1., 1.));
float angle = 1. * iGlobalTime;
float c = cos(angle);
float s = sin(angle);
mat4 matrix;
matrix[0][0] = n[0]*n[0]*(1.-c)+c;
matrix[0][1] = n[0]*n[1]*(1.-c)-n[2]*s;
matrix[0][2] = n[2]*n[0]*(1.-c)+n[1]*s;
matrix[1][0] = n[0]*n[1]*(1.-c)+n[2]*s;
matrix[1][1] = n[1]*n[1]*(1.-c)+c;
matrix[1][2] = n[1]*n[2]*(1.-c)-n[0]*s;
matrix[2][0] = n[2]*n[0]*(1.-c)-n[1]*s;
matrix[2][1] = n[1]*n[2]*(1.-c)+n[0]*s;
matrix[2][2] = n[2]*n[2]*(1.-c)+c;
eye = (matrix * vec4(eye, 1.)).xyz;
xvec = (matrix * vec4(xvec, 1.)).xyz;
yvec = (matrix * vec4(yvec, 1.)).xyz;

時間が進むとiGlobalTimeが増えてmatrixの成分が変化することで、3つの軸の向きが変化して回転するようになっています。(今回はShaderの説明ではなくこんなものが作れるよという紹介でした)

おわりに

合同変換から始まって線形写像や直交行列の話もしながら、運動について話を進めてきました。ここまで読んでいただきありがとうございました。

上の話では出てこなかったのですが、オイラー角やロドリゲスの公式以外にもロールピッチョー角による回転行列もあってz軸、y軸、x軸の順に周りに回転させる行列もあります。また行列ではなく四元数を用いて合同変換および運動を表現する方法もあります。(気になる方は調べてください)

明日は最終回で@to-hutohuの「入部おめでとうございます&これからも入部歓迎です」と@Hummingの「誰でもわかる!モンハンにおけるダメージ計算」です。お楽しみに~

参考文献

斎藤正彦.線形代数学入門.東京大学出版会,1966

ランダウ,リフシッツ.力学.東京図書株式会社,1974

このエントリーをはてなブックマークに追加

コメントを残す

メールアドレスが公開されることはありません。