Flash Power Session 2008 in Osaka
変換行列 − Matrixクラス
Date: 2008年9月13日 |
Product: Flash CS3 Professinal/ActionScript 3.0 |
■サンプルFLAファイル(Zip圧縮/約104KB)
SWFの再生にはFlash Player 9以降、ソースFLAファイルを開くにはFlash CS3 Professional以降が必要。
|
■PDF特別公開
10月中旬発売予定の拙著『ActionScript 3.0プロフェッショナルガイド』から「テクニック編」のT.5.1「Matrixクラスが表す変換行列」の解説をPDFで公開。ただし、約640ページに及ぶ書籍の終盤の部分なので、Flash Power Sessionで行った説明よりは少し高度な内容になっている。
|
|
1. 変換行列とは
3×3の行列で、インスタンスの座標空間を変換する。うち、最初の2行の6要素が制御の対象。
|
a: 水平方向の伸縮率 = 変換後の幅/もとの幅
b: 垂直方向の傾斜率 = 垂直方向の傾斜/もとの幅
c: 水平方向の傾斜率 = 水平方向の傾斜/もとの高さ
d: 垂直方向の伸縮率 = 変換後の高さ/もとの高さ
|
図001■変換行列のシミュレーション
SWFを開いて、[Matrix]または[Rotate]のラジオボタンを選択したうえで、UIのボタンやテキストフィールドに数値を入力する。
|
Matricクラスで変換行列を作成して、インスタンスに適用する手順は、つぎのとおり。
【Matrixクラスで変換行列をインスタンスに適用する手順】
- new Matrix()の呼出しにより、Matrixインスタンスを生成する。
- Matrixインスタンスの上記プロパティ(a、b、c、d、tx、ty)に、変換のための値を設定する。
- Matrixインスタンスを、変換対象のインスタンスのtransform.matrixプロパティに設定する。
たとえば、タイムラインに配置したMovieClipインスタンスmy_mcに対して、幅を2倍にし、高さは1.5倍で、水平および垂直方向に0.5傾斜をかけるには、Matrixクラスを用いたつぎのようなフレームアクションを記述する(図002)。
var myMatrix:Matrix = new Matrix();
myMatrix.a = 2;
myMatrix.b = 0.5;
myMatrix.c = 0.5;
myMatrix.d = 1.5;
my_mc.transform.matrix = myMatrix;
図002■インスタンスのtransform.matrixに変換行列(Matrixインスタンス)を適用する
インスタンスは、幅が2倍、高さは1.5倍で、水平および垂直方向に0.5の傾斜がかかっている。
|
2. インスタンスの角をドラッグして変形する
インスタンスの角にドラッグできるポイントとなるインスタンスを置き、その位置に合わせて変換行列を適用してみたい。ポイントのインスタンスには、ドラッグするためのフレームアクションが記述してある。そして、インスタンスの変形は、ポイントからメインタイムラインの関数xTransform()を呼出して行っている(図003)[*1]。
図003■ドラッグするポイントのインスタンスに記述されたフレームアクション
ドラッグの処理と、ターゲットのインスタンスを変換するためのメインタイムラインの関数xTransform()の呼出しが記述されている。
|
そこで、メインタイムラインに関数xTransform()を定義すれば、ポイントをドラッグする間自動的に呼出されることになる。この関数内に、インスタンスを変換するための処理を記述する。関数の定義の仕方は、つぎのとおり(今回の関数に引数はなく、括弧()の後のデータ型にはvoidを指定する)。
【関数の定義】
function 関数名([引数:データ型]):データ型 {
// 関数が行うべき処理
}
たとえば、メインタイムラインの関数xTransform()に以下のような処理を記述すると、ポイントをドラッグしたとき(その方向や動きには関係なく)、インスタンスの幅が2倍に拡大する。ただし、もとのインスタンスの幅を基準にするので、拡大し続ける訳ではないことに注意。
function xTransform():void {
var myMatrix:Matrix = new Matrix();
myMatrix.a = 2;
my_mc.transform.matrix = myMatrix;
}
まず右上隅に置いたポイントで、インスタンスの変形を試してみる。前述の水平方向の伸縮率aと垂直方向の傾斜率bの計算式を使えば、スクリプトの処理は以下のようになる(スクリプト001)。なお、インスタンスは左上隅(基準点)を、配置先タイムラインの基準点(0, 0)に合わせておく。右上隅のポイントのインスタンス名は、point1_mcだ。
スクリプト001■右上隅のポイントのドラッグによりインスタンスを変形する
// タイムライン: メイン
// 第1フレームアクション
function xTransform():void {
var myMatrix:Matrix = new Matrix();
my_mc.transform.matrix = myMatrix; // デフォルトの変換行列を適用
var nWidth:Number = my_mc.width;
var n1x:Number = point1_mc.x;
var n1y:Number = point1_mc.y;
myMatrix.a = n1x/nWidth;
myMatrix.b = n1y/nWidth;
my_mc.transform.matrix = myMatrix;
}
|
上記スクリプト001で注意すべきは、基準となるインスタンスの幅(変数nWidthの値)だ。これはインスタンスが変換される前の、もともとの値を用いなければならない。そのため、上記スクリプト001では、インスタンスのtransform.matrixプロパティに新規のMatrixインスタンス(デフォルトの変換行列)を適用したうえで、widthプロパティの値を取っている。
[ムービープレビュー]で試すと、右上隅のポイントをドラッグすれば、その位置に合わせてインスタンスが平行四辺形に変形する(図004)。
図004■右上隅のポイントをドラッグするとインスタンスが変形する
関数xTransform()により、インスタンスに変換行列が適用されて、平行四辺形に変形される。
|
3. ふたつのポイントをドラッグしてインスタンスを変形する
右上隅のポイントひとつでインスタンスが正しく変形されることを確かめたら、左下隅に置いたポイントに対しても、同じ要領で処理を加える(スクリプト002)。動作は小分けして確認し、拡張していくことが、スクリプトを早く正確に組上げるコツになる。左下隅のポイントには、point2_mcというインスタンス名をつけた。
スクリプト002■左下隅のポイントのドラッグもインスタンスの変形に加える
// タイムライン: メイン
// 第1フレームアクション
function xTransform():void {
var myMatrix:Matrix = new Matrix();
my_mc.transform.matrix = myMatrix;
var nWidth:Number = my_mc.width;
var nHeight:Number = my_mc.height;
var n1x:Number = point1_mc.x;
var n1y:Number = point1_mc.y;
var n2x:Number = point2_mc.x;
var n2y:Number = point2_mc.y;
myMatrix.a = n1x/nWidth;
myMatrix.b = n1y/nWidth;
myMatrix.c = n2x/nHeight;
myMatrix.d = n2y/nHeight;
my_mc.transform.matrix = myMatrix;
}
|
[ムービープレビュー]で確かめると、ふたつのポイントのドラッグ位置に合わせて、インスタンスが自由な平行四辺形に変形できる(図005)。
図005■ふたつのポイントをドラッグしてインスタンスが変形できる
関数xTransform()に左下隅のポイント移動による変換行列の操作が加わり、自由な形状の平行四辺形に変形できる。
|
上記スクリプト002のMatrixインスタンスのプロパティ値を代入している右辺に注目してほしい。分数(割り算)の分子・分母が規則的なパターンで並んでいる。行列は、このように要素を規則的なパターンで計算できるように並べたものだと考えられる[*2]。
myMatrix.a = n1x/nWidth;
myMatrix.b = n1y/nWidth;
myMatrix.c = n2x/nHeight;
myMatrix.d = n2y/nHeight;
[*2] 行列はパラメータを処理しやすいように並べたものと見ると、フィルタなどの設定パネルにも似ている。
図006■インスタンスのカラースタイルの[拡張効果]ダイアログボックス
インスタンスのカラーについて、赤(R)緑(G)青(B)アルファの各チャネルごとにパラメータを設定できる。
|
|
4. 3つのポイントによりインスタンスを自由な平行四辺形に変換する
もうひとつ左上隅のポイントを加えれば、かたちだけでなく、位置も自由に変えられる。移動(「平行移動」という)するには、Matrixクラスのtxおよびtyプロパティを操作する(スクリプト003)。左上隅のポイントには、point0_mcというインスタンス名を設定した。
スクリプト003■3つのポイントのドラッグで自由な平行四辺形に変形する
// タイムライン: メイン;
// 第1フレームアクション
function xTransform():void {
var myMatrix:Matrix = new Matrix();
my_mc.transform.matrix = myMatrix;
var nWidth:Number = my_mc.width;
var nHeight:Number = my_mc.height;
var n0x:Number = point0_mc.x;
var n0y:Number = point0_mc.y;
var n1x:Number = point1_mc.x-n0x;
var n1y:Number = point1_mc.y-n0y;
var n2x:Number = point2_mc.x-n0x;
var n2y:Number = point2_mc.y-n0y;
myMatrix.a = n1x/nWidth;
myMatrix.b = n1y/nWidth;
myMatrix.c = n2x/nHeight;
myMatrix.d = n2y/nHeight;
myMatrix.tx = n0x;
myMatrix.ty = n0y;
my_mc.transform.matrix=myMatrix;
}
|
インスタンスの左上隅(point0_mc)が移動するようになるので、右上隅(point1_mc)と左下隅(point2_mc)の移動ピクセル数を計算するとき、左上隅座標との差を取る必要があることに注意したい。[ムービープレビュー]を見ると、3つのポイントをドラッグすることにより、インスタンスを自由な平行四辺形に変換することができる(図007)。
図007■ドラッグした3点のポイントに合わせてインスタンスが変形する
インスタンスの位置も含めて、自由な平行四辺形に変換できる。
|
長方形を平行四辺形に変換するという処理は、3次元の表現で求められる。したがって、変換行列を応用すれば、3次元の立方体のアニメーションをシミュレートすることもできる(図008)。
図008■立方体を3次元で回転する
6面の角の座標と変形を管理すれば、3次元の立方体が表現できる。このムービーの作成方法も、拙著で解説している。
|
作成者: 野中文雄
作成日: 2008年9月16日