回転と拡大・縮小
まずは回転からです。回転を行うには「rotateメソッド」を使用します。
マトリクス.rotate(ラジアン);
rotateメソッドの引数は,私たちが普段慣れ親しんでいる「0度~360度」の角度の単位(度数法)ではなく「ラジアン」という単位(弧度法)を使います。ある角度をラジアンに変換するには,次の式を用います*1。
ラジアン = 角度 * 円周率 / 180
ActionScriptでは円周率は「Math.PI」として提供されていますので,上の式は,
ラジアン = 角度 * Math.PI / 180となりますね。
このことを踏まえ,45度回転させて絵を書き込むには,次のようにコードを記述します(図1)。
図1: 回転して書き込む(クリックするとムービーを表示します)
回転移動させて書き込む処理(抜粋)
//変形情報を管理するMatrixクラスのインスタンスを生成 var _mat:Matrix = new Matrix(); //45度回転させるため,「45度」をラジアンに変換 var _radian:Number = 45 * Math.PI / 180; //変換した値を使って,回転の情報を更新 _mat.rotate(_radian); //そのままだと位置的に見にくいので,位置の情報も更新 _mat.translate(100,50); //マトリクスの情報を元に書き込む canvas.draw(stamp,_mat);
ラジアンの計算を行い,rotationメソッドの引数へと指定すれば,指定した角度で回転を行うことが確認できますね*2。
では,続いて,拡大・縮小する場合の処理を作成してみましょう。拡大・縮小を行うには,「scaleメソッド」を使用します。
マトリクス.scale(x軸方向の拡大率, y軸方向の拡大率);
ちょうど半分の大きさ(0.5倍)で書き込みたい場合には,次のようにコードを記述します(図2)。
図2: 半分の大きさで書き込む(クリックするとムービーを表示します)
拡大・縮小を行うコード
//変形情報を管理するMatrixクラスのインスタンスを生成 var _mat:Matrix = new Matrix(); //横方向・縦方向それぞれの倍率を「0.5倍」する _mat.scale(0.5,0.5); //そのままだと位置的に見にくいので,位置の情報も更新 _mat.translate(100,50); //マトリクスの情報を元に書き込む canvas.draw(stamp,_mat);
拡大する場合にはscaleメソッドの引数に1より大きい数を,縮小する場合には1より小さい数を指定すればOKです。また,反転させたい場合には,-1等の負の数値を指定します。
これら,移動(translateメソッド),回転(rotateメソッド),拡大・縮小(scaleメソッド)などの処理は,Matrixプロパティの六つの行列の要素の値のうち,必要なものを適宜変化させています。行列のままでは直観的にどういう情報なのかがわかりにくい私たちのために,わかりやすいよう「translate」「rotate」「scale」等の英単語のメソッドを用意してくれているわけですね。
情報を保持するMatrixクラスのインスタンス
さて,ここで一つ,実験をしてみましょう。先ほど45度の回転を実行した図2の処理,この処理は,回転後のビットマップが見やすい位置に来るように,rotateメソッドで回転した後に,translateメソッドで(100,50)の位置へと移動させていました。この「回転」と「移動」の処理の順番を変更すると,結果はどうなるでしょうか?結果は図3のようになります。
図3: 順序を入れ替えて実行(クリックするとムービーを表示します)
移動させてから回転させるコード(抜粋)
//変形情報を管理するMatrixクラスのインスタンスを生成 var _mat:Matrix = new Matrix(); //位置の情報を更新 _mat.translate(100,50); //45度回転させるため,「45度」をラジアンに変換 var _radian:Number = 45 * Math.PI / 180; //変換した値を使って,回転の情報を更新 _mat.rotate(_radian); //マトリクスの情報を元に書き込む canvas.draw(stamp,_mat);
「rotate→translate」の順番で実行した結果と,「translate→rotate」の順番で実行した結果はずいぶんと異なりますね。このように,Matrixクラスの変形情報は,そのメソッドの実行順序も重要になってきます*3。
さてさて,二つのメソッドを連続して実行すると,二つのメソッドで指定した変形の情報を順番に反映した結果となる,ということは,Matrixクラスのインスタンスは,一度指定した変形の情報を,そのまま保持しているということになりますね。
と,いうことは,「x方向に50ピクセルずつずらして書き込む」というような繰り返し処理を行う際にも,一つ前の処理の情報をそのまま使って次のようにコードを書けばOKです(図4)。とてもシンプルな処理ですね。
図4: 繰り返し50ピクセル移動させて書き込む(クリックするとムービーを表示します)
情報を更新して書き込む(抜粋)
var _mat:Matrix = new Matrix(); for(var i:Number = 0;i<4;i++){ canvas.draw(stamp,_mat); //描画 mat.translate(50,0); //情報更新 }
今度は,ビットマップ「canvas」の横方向に敷き詰めるような処理を作成してみましょう。これは,BitmapDataクラスの「widthプロパティ」を使って,ビットマップの横幅を取得し,その値とMatrixクラスのx軸方向の位置を管理するプロパティである「txプロパティ」の値を使って,次のようにコードを記述することができます。これまたシンプルな処理ですね。
横方向に敷き詰める(抜粋)
var _mat:Matrix = new Matrix(); _mat.identity(); while(_mat.tx<canvas.width){ canvas.draw(stamp,_mat); //描画 _mat.translate(50_xTrans,0); //情報更新 }