読者です 読者をやめる 読者になる 読者になる

デジタル・デザイン・ラボラトリーな日々

アラフィフプログラマーが数学と物理を基礎からやり直す

回転行列を理解してみる

2D プログラム

回転で使用した式は以下となる。

r.x = cosθ * p.x - sinθ * p.y
r.y = sinθ * p.x + cosθ * p.y

数学的に式を単純化してみると、
(r.x,r.y)を分けているのを「r」のみに
(p.x,p.y)を分けているのを「p」のみに
sinとcosが入った何かを「A」と置き換えしてみると

r = Ap

Aとpをどうにかすると、rとなる。

Aを行列(Matrix)で表現してみます。

   | cos -sin |
A =|          |
   | sin  cos |

Aを横に2個、縦に2個の計4個の数字を並べてあり、
横に並べたのを行といい, 縦に並べたのを列といいます。

r.x = cosθ * p.x - sinθ * p.y
r.y = sinθ * p.x + cosθ * p.y

の式を行列で再表現してみると以下のようになります。

| r.x |   | cos -sin || p.x |
|     | = |          ||     |
| r.y |   | sin  cos || p.y |


行列計算のおさらいとして実際に数値を入れて計算をしてみると

| x |   |1 2||5|
|   | = |   || |
| y |   |3 4||6|

 1 * 5 + 2 * 6 =  5 + 12 = 17
 3 * 5 + 4 * 6 = 15 + 24 = 39
(x,y) = (17,39) となります。


回転だけでなく、拡大縮小と平行移動も考えてみます。

拡大縮小は単純に点(x,y)に倍率を掛けてあげればよい。
点(x, y)を原点に関してx軸方向にsx倍、Y軸方向にsy倍する行列は以下となります。

| r.x |   | sx 0 || p.x |
|     | = |      ||     |
| r.y |   | 0  sy|| p.y |

r.x = sx * p.x +  0 * p.y
r.y =  0 * p.x + sy * p.y

実際に数値を入れて計算をしてみます。点P(3,4)を2倍にする。

| x |   |2 0||3|
|   | = |   || |
| y |   |0 2||4|

 2 * 3 + 0 * 4 =  6 + 0 = 6
 0 * 3 + 2 * 4 =  0 + 8 = 8
(x,y) = (6,8) となります。


次は平行移動です。
平行移動は素直に座標に対して、加算すればいいですね。
点P(1,2)にx方向に3、y方向に1を加えた点Rの位置は

r.x = 1 + 3
r.y = 2 + 1

となり、点R(4,3)となります。

加算する値を「q」で表した場合の式は以下になります。

 r.x = p.x + q.x
 r.y = p.y + q.y

行列で表現した場合には、今までと違って行列の掛け算ではなく行列の足し算となります。

| r.x |   | q.x |   | p.x |
|     | = |     | + |     |
| r.y |   | q.y |   | p.y |


回転と拡大縮小と平行移動をまとめて操作したい場合、
回転と拡大縮小は行列の掛け算で平行移動だけが行列の足し算になると扱いにくいので
平行移動も行列の掛け算で表現できるようにします。

行列の掛け算といっても、計算する列が変わると加算してましたよね。
つまり、列を増やしてあげれば加算できることになります。

| r.x |   | 1 0 t.x || p.x |
| r.y |   | 0 1 t.y || p.y |
|  1  | = | 0 0  1  ||  1  |

r.x = 1 * p.x + 0 * p.y + t.x * 1
r.y = 0 * p.x + 1 * p.y + t.y * 1
r.x = p.x + t.x
r.y = p.y + t.y

最後の「1」は、行列の乗算では掛けられる行列の列数(3)と掛ける行列の行数(3)が同じである必要があるため、ダミーとなります。

回転と拡大縮小と平行移動を全部行列の掛け算で表せることが出来ました。
では、並べてみます。

回転行列
| r.x |   | cos -sin || p.x |
|     | = |          ||     |
| r.y |   | sin  cos || p.y |

拡大縮小行列
| r.x |   | sx 0  || p.x |
|     | = |       ||     |
| r.y |   | 0  sy || p.y |

平行移動行列
| r.x |   | 1 0 t.x || p.x |
| r.y | = | 0 1 t.y || p.y |
|  1  |   | 0 0  1  ||  1  |

平行移動だけが3×3行列となっていますので、回転と拡大縮小も平行移動の行列数に合わせた式が以下になります。

回転行列
| r.x |    | cos -sin 0 || p.x |
| r.y | =  | sin  cos 0 || p.y |
|  1  |    |  0    0  1 ||  1  |

拡大縮小行列
| r.x |    | sx  0  0 || p.x |
| r.y | =  | 0  sy  0 || p.y |
|  1  |    | 0   0  1 ||  1  |

平行移動行列
| r.x |    | 1 0 t.x || p.x |
| r.y | =  | 0 1 t.y || p.y |
|  1  |    | 0 0  1  ||  1  |

参考サイト
イメージングソリューション
使える数学 > 回転行列、拡大縮小行列、平行移動行列
http://imagingsolution.net/math/rotation-scaling-translation-matrix/
ActionScript 3.0 コンポーネントリファレンスガイド Matrix
http://livedocs.adobe.com/flash/9.0_jp/ActionScriptLangRefV3/flash/geom/Matrix.html
日本語版には行列の値に間違いがあります、英語版は修正されています。
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Matrix.html