Matrixクラスは以下のような機会で用いることがあります。
・DisplayObjectインスタンスを移動、拡大・縮小、回転させる
・BitmapDataクラスのdrawメソッドの引数として使用
Matrixとは数学で言うと行列なのですが、行列の知識がなくとも簡単に利用できてしまいます。それで充分な気もしますが、数学的に行列を理解するこで、更に深くMatrixクラスを理解するのが今回の目的です。
Matrix – wonderfl build flash online
まず、DisplayObject(ここでは_rect)からMatrixインスタンスを取得する。
1 2 3 |
//matrix _myMatrix = _rect.transform.matrix; trace(_myMatrix);//(a=1, b=0, c=0, d=1, tx=50, ty=50) |
MatrixインスタンスをMatrixクラスのメソッド、translate()、scale()、rotate()によって変換後、
DisplayObjectのmatrixプロパティに設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
//移動 private function click1(evt:MouseEvent):void { _myMatrix.translate( -50, -50); _rect.transform.matrix = _myMatrix; } //拡大・縮小 private function click2(evt:MouseEvent):void { _myMatrix.scale(1.5, 1.5); _rect.transform.matrix = _myMatrix; } //回転 private function click3(evt:MouseEvent):void { _myMatrix.rotate(Math.PI / 3); _rect.transform.matrix = _myMatrix; } |
行列は以下のように縦横に数値を並べたものです。行数と列数は任意です。
Matrixクラスで用いる行列は以下のようになります。
ただし、a,b,c,d,tx,tyに入る値は変換の種類によって違っていて、それぞれ以下のようになります。
移動の場合↓
拡大・縮小の場合↓
回転の場合↓
このような変換行列をxy座標に掛けることによって変換後の座標を求めることができます。
Matrixクラスで行われている掛け算は以下のようになります。
注意して欲しいのは(x,y)で表される座標は、”1″をくっつけて(x,y,1)になります(移動を扱うためです)。
具体的な計算例を示したいと思います。
四角形が置かれています。四隅の座標は以下のようなっています。
これをx方向に-50、y方向に-50移動させてみます。
目視で答えは簡単にわかりますが、左上が原点にくるように移動されるはずです。
まず、移動なのでa=d=1,b=c=0となります。
そして、x方向に-50だけ移動したいので、tx=-50となります。
同様に、y方向に-50だけ移動したいので、ty=-50です。
これらの値を上記の計算式にあてはめます。
これより、それぞれの座標は次のように変換されます。
(50-50 50-50)=(0 0)
(200-50 50-50)=(150 0)
(200-50 150-50)=(150 100)
(50-50 150-50)=(0 100)
四角形は無事、左上が原点にくるように移動されました。
Matrixクラスではこういった処理を行ってくれているのです。
実際にMatrixクラスを使用する際に、こういった行列計算を意識することはありませんが、
行列の知識がいつか何かの役に立つかもしれません。願わくば。。。
wonderflのコード↓
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
package { import flash.display.Sprite; import flash.events.*; import flash.events.TextEvent; import flash.text.TextField; import flash.geom.Matrix; import caurina.transitions.Tweener; /** * ... * @author masaoka */ [SWF(frameRate="30", width="465", height="465")] public class Main extends Sprite { private var _rect:Sprite; private var _myMatrix:Matrix; public function Main():void { //四角形の描画 _rect = new Sprite(); _rect.graphics.beginFill(0xFF6600, 0.8); _rect.graphics.drawRect(0, 0, 150, 100); _rect.graphics.endFill(); _rect.x = 50; _rect.y = 50; this.addChild(_rect); //matrix _myMatrix = _rect.transform.matrix; trace(_myMatrix);//(a=1, b=0, c=0, d=1, tx=50, ty=50) var btn1:Sprite = new Sprite(); creatBtn(btn1, 350, 10, "translate"); var btn2:Sprite = new Sprite(); creatBtn(btn2, 350, 50, "scale"); var btn3:Sprite = new Sprite(); creatBtn(btn3, 350, 90, "rotate"); var btnClear:Sprite = new Sprite(); creatBtn(btnClear, 350, 400, "clear"); btn1.addEventListener(MouseEvent.CLICK, click1); btn2.addEventListener(MouseEvent.CLICK, click2); btn3.addEventListener(MouseEvent.CLICK, click3); btnClear.addEventListener(MouseEvent.CLICK, clickClear); } //移動 private function click1(evt:MouseEvent):void { _myMatrix.translate( -50, -50); _rect.transform.matrix = _myMatrix; } //拡大・縮小 private function click2(evt:MouseEvent):void { _myMatrix.scale(1.5, 1.5); _rect.transform.matrix = _myMatrix; } //回転 private function click3(evt:MouseEvent):void { _myMatrix.rotate(Math.PI / 3); _rect.transform.matrix = _myMatrix; } private function clickClear(evt:MouseEvent):void { _myMatrix.a = 1; _myMatrix.b = 0; _myMatrix.c = 0; _myMatrix.d = 1; _myMatrix.tx = 50; _myMatrix.ty = 50; _rect.transform.matrix = _myMatrix; } private function creatBtn(btn:Sprite,_x:Number, _y:Number,_text:String):Sprite { //var btn:Sprite = new Sprite(); btn.graphics.beginFill(0x0FFFF0,0.5); btn.graphics.drawRoundRect(0, 0, 80, 30, 10); btn.graphics.endFill(); btn.x = _x; btn.y = _y; this.addChild(btn); var tf:TextField = new TextField(); tf.text = _text; tf.selectable = false; tf.x = 20; tf.y = 5; btn.addChildAt(tf,0); return btn; } } } |