[Study]Matrixクラスをつかってみる?かどうか考え中

今の今までMatrixクラスを使わずに人生を歩んできた私ですが、他に書くことがないのでちょっと触ってみることにしました。
 
そもそもMatrixクラスで何ができるのか?
書籍やヘルプを見た感じだと

  • 平行移動
  • 拡大 / 縮小
  • 回転
  • 傾斜または変形

ができるらしい…

パッと見、

  • 平行移動はx,yプロパティの変更と同じっぽい
  • 拡大 / 縮小はscaleX,scaleYの変更と同じっぽい
  • 回転はrotationの変更と同じっぽい

じゃあ使わなくてもいいんじゃね?っということで終了。になりがちだが、
「傾斜または変形」これはMatrixクラスを使わないと大変かもしれない。
ということで仕方なく
「君、CS4のインストールは終わっているのかね?では試してみるかな」
 
まずは基本中の基本平行移動
ばかばかしい(x,yのプロパティ変更で済むのに)と思いながらも、取りあえずステージ上にあるMC(square)をXY各軸50pxづつ移動してみる。
squareの初期座標はわかりやすくswfの基準点(0, 0)で配置。
まずは変換マトリックス自体を用意する為に、new Matrix()してMatrixクラスのインスタンスを生成。
[code lang=”actionscript3″]
var matrix:Matrix = new Matrix();
[/code]
これをいきなりsquareに適用しても全く効果がでない。
そこでMatrixクラスのメソッドであるtranslateを指定する。
[code lang=”actionscript3″]
// 引数は平行移動時のX軸移動量とY軸移動量
matrix.translate(50, 50);
[/code]
ようやくできたMatrixインスタンスをsquareに適用してみる
[code lang=”actionscript3″]
square.transform.matrix = matrix;
[/code]
以下が実行結果。
どうやらできたみたい。
でもこれだったらxyプロパティの変更でやるかな。
 

Get Adobe Flash player


[code lang=”actionscript3″]
var matrix:Matrix = new Matrix();
matrix.translate(50, 50);
square.transform.matrix = matrix;
[/code]
う~む、案の定平行移動をやっただけでは利点が感じられない。
なにより移動後の座標ではなく、移動量を指定するあたりがなんとも。
 
じゃあ次、拡大 / 縮小
あまり期待できないが、取りあえず試してみる。
せっかくだから平行移動した後に続けてやってみよう。
取りあえず幅高さとも2倍にする為、Matrixクラスのメソッドであるscaleを指定する。
[code lang=”actionscript3″]
// 引数はX軸方向とY軸方向の倍率
matrix.scale(2, 2);
[/code]
以下が実行結果。
2倍になった!にはなったけど、座標も変わってる?
 

Get Adobe Flash player


[code lang=”actionscript3″]
var matrix:Matrix = new Matrix();
matrix.translate(50, 50);
square.transform.matrix = matrix;
matrix.scale(2, 2);
square.transform.matrix = matrix;
[/code]
コレだけでは何が起きたのか、ぶっちゃけ話が見えない。
最初のtranslateの段階でsquareはステージ上の(50, 50)に位置し
次のscale実行後は(100, 100)に位置している。
倍率変更は指示したけど平行移動は最初だけなのに、はぁ?って感じ。
「これがMatrixクラスかぁッ!!」

行列の計算は何をしている!
ここまではメソッドの実行結果を見てきただけなので、この謎を解くには実際にどういう計算に基づいてこうなったのか把握する必要がありそうだ。
まず最初のtranslateだが、ヘルプには以下の表?が書いてある。

Get Adobe Flash player


これはいったい何なのか。
唯一わかるのはtranslateの引数2つ(tx, ty)の行き先が右列の上段と中段に入るってことぐらい。
その他の0や1は何?これらがどう計算されてsquareに反映されるのだろうか?

行列の計算 足し算
行列の足し算はこんな感じでするみたい。

Get Adobe Flash player


行列の計算 掛け算
行列の掛け算。ちょっとわかりづらいけどflashのMatrixクラスはこの掛け算を使っているようだ。

Get Adobe Flash player

行列の基本的な計算方法が分かったところで、本当にそうなるのか実際の計算式に当てはめて計算してみる。
がしかしその前に!
Flashにおける行列の行数・列数がどうなっているかを知っておく必要がある。
上でやった計算方法の例では2行×2列の掛け算だが、Flashではそれでは足りないのである。
なぜならそれは・・・

  • 行列の平行移動を行うには3列目が必要
  • 掛けられる行列(左)の行数と掛合わせる行列(右)の列数が等しくなくてはならない

これで分かる人はこの記事を読んでいないだろう。
ということでひとつずつ確認していく。

行列の平行移動を行うには3列目が必要
Flashの行列は掛け算を行っており、2次元上のある特定の座標へ平行移動するには3列目が必要になるっぽい。
その為、拡大 / 縮小や回転の行列計算では2行2列で済んでしまうのだが、平行移動用にわざわざ3列目を増やしたようだ。
[code lang=”actionscript3″]
var matrix:Matrix = new Matrix();
matrix.translate(50, 50);
square.transform.matrix = matrix;
[/code]
最初にやったヤシ。これをFlashの行列計算であらわすと

Get Adobe Flash player


掛けられる行列(左)のa~dは平行移動時は任意ではあるものの固定値としてa=1,b=0,c=0,d=1が入る。
txとtyはメソッドの引数値が入る。
3行目はこの平行移動の為に3列目が追加された影響で、後の行列同士の計算用に帳尻を合わせるために存在する(後述)。値は固定値で0,0,1が入っており変更することは決っしてできない。
掛合わせる行列(右)はsquareを例にとってみると、squareを構成するすべてのピクセルのx座標、y座標がそれぞれ1行目、2行目に入る。
3行目は掛けられる行列(左)と同じくして平行移動の為に3列目が追加された影響で、固定値1が存在する。

掛けられる行列(左)の行数と掛合わせる行列(右)の列数が等しくなくてはならない
上でも少し触れたが、2行×2列で再現できない平行移動を、2行×3列にすることで実装しても拡大 / 縮小や回転といった行列同士の計算を行う際、2行×2列2行×3列といったバラバラの行列を掛け合わせることはできない。その為、計算結果に影響が出ない値を固定値とした3行目が存在するようだ。よってこの3行目は触ることができない。

待て次回!!