●解説
Vector3Dクラスは3次元空間の座標を扱います。3次元座標をコンピュータディスプレイの2次元平面に投影することは、「透視投影」といいます。Vector3D.project()メソッドを用いると、Vector3Dインスタンスの座標を透視投影できます。そのためには、焦点距離にもとづく投影の比率を定めなければなりません。投影の比率は、簡単な比例計算により、つぎのように求められます(図06-16-01)。
投影像の大きさ/オリジナルの大きさ = 焦点距離/(焦点距離 + z方向距離)
投影像の大きさ = オリジナルの大きさ×焦点距離/(焦点距離 + z方向距離)
図06-16-01■焦点距離とz方向距離が投影像の大きさを決める【Fig09-002.png】
Vector3Dインスタンスは、実際には4次元のベクトルです。3次元のxyz座標に加え、オプションとしてベクトルの第4成分(要素)となるVector3D.wプロパティをもちます(図06-16-02)。透視投影の比率は、このVector3D.wプロパティに設定します。ただし、Vector3D.project()メソッドは、Vector3D.x/Vector3D.y/Vector3D.zプロパティの各値を、Vector3D.wプロパティ値で割り算します。したがって、Vector3D.wプロパティには、つぎの計算値を設定します。
Vector3D.wプロパティ = (焦点距離 + Vector3D.zプロパティ値)/焦点距離
図06-16-02■Vector3Dインスタンスが表すベクトル
[編集者向け注釈] 図は[ヘルプ]から引用したものなので、イラストもしくは表組などで再作成してください。
Vector3D.project()メソッドは、参照したインスタンスのxyz座標を直接書替えます。ですから、もとのインスタンスを保持するためには、Vector3D.clone()メソッドで予めVector3Dオブジェクトを複製します。また、Matrix3D.transformVector()メソッドを使うと、Matrix3Dオブジェクトの変換行列でVector3Dインスタンスの3次元座標を変換することができます。
→関連項目
「インスタンスを3次元変換行列で伸縮・回転したい」「3次元変換行列でインスタンスに複数の変換を加えたい」
Vector3Dクラス |
パッケージ
|
flash.geom
|
継承
|
Vector3D → Object
|
Vector3D()コンストラクタ |
ASタイプ |
M |
ランタイムバージョン
|
AIR 1.5/Flash Player 10
|
文法
|
Vector3D(x:Number = 0, y:Number = 0, z:Number = 0, w:Number = 0)
|
意味
|
Vector3Dインスタンスを生成します。
|
引数
|
x:Number ― インスタンスのx座標値。デフォルト値は0。/y:Number ― インスタンスのy座標値。デフォルト値は0。/z:Number ― インスタンスのz座標値。デフォルト値は0。/w:Number ― インスタンスのw値(オプション)。透視投影比率などを納める。デフォルト値は0。
|
wプロパティ |
ASタイプ
|
P |
ランタイムバージョン
|
AIR 1.5/Flash Player 10
|
文法
|
matrix:Matrix
|
意味
|
Vector3Dインスタンスが表すベクトルの第4成分(要素)。Vector3D.project()メソッドにより、xyz座標値を除する値。
|
プロパティ値
|
Vector3Dインスタンスが表すベクトルの第4成分値。透視投影比率などを納める。
|
project()メソッド |
ASタイプ
|
M |
ランタイムバージョン
|
AIR 1.5/Flash Player 10
|
文法
|
project():void
|
意味
|
Vector3Dインスタンスのxyzの各座標値をVector3D.wプロパティの値で除する。3次元空間から2次元平面への座標の透視投影変換などに用いられる。
|
引数
|
なし。
|
戻り値
|
なし。
|
clone()メソッド |
ASタイプ
|
M |
ランタイムバージョン
|
AIR 1.5/Flash Player 10
|
文法
|
clone():Vector3D
|
意味
|
Vector3Dインスタンス複製して、新たなオブジェクトとして返す。
|
引数
|
xScale:Number…水平方向に拡大・縮小として乗じる比率。/yScale:Number…垂直方向に拡大・縮小として乗じる比率。/zScale:Number…垂直方向に拡大・縮小として乗じる比率。
|
戻り値
|
複製された新たなVector3Dインスタンス。
|
Matrix3Dクラス |
パッケージ
|
flash.geom
|
継承
|
Matrix3D → Object
|
transformVector()メソッド |
ASタイプ
|
M |
ランタイムバージョン
|
AIR 1.5/Flash Player 10
|
文法
|
transformVector(targetVector3D:Vector3D):Vector3D
|
意味
|
Matrix3Dオブジェクトの変換行列を用いて、Vector3Dインスタンスの座標を変換し、新たなVector3Dオブジェクトとして返す。
|
引数
|
targetVector3D:Vector3D…座標を変換する対象のVector3Dインスタンス。
|
戻り値
|
座標変換された新たなVector3Dインスタンス。
|
○記述例
3次元空間に矩形の4隅の座標をVector3Dインスタンスで指定し、回転の変換を加えたうえで、タイムライン上にワイヤーフレームで回る矩形を描いてみましょう。4隅の初期位置はz座標を0とし、原点(0, 0, 0)を中心に1辺の半分を変数(nUnit)に代入して、下図06-16-03のように設定します。
図06-16-03■3次元空間における矩形の4隅の座標【06_16_Vector3D_project_001.png】
以下のスクリプト06-16-01は、3次元空間で矩形の4隅の座標をマウスポインタの水平位置に応じてy軸で回転し、タイムラインに動的に配置したSpriteインスタンスに4辺をワイヤーフレームで描きます(図06-16-04)。4隅の座標はVector3Dオブジェクトで生成し、Vectorインスタンス(myVectors)に納めています。
図06-16-04■ワイヤーフレームの矩形がマウスポインタの位置に応じて水平回転する【06_16_Vector3D_project_002.png】
DisplayObject.enterFrameイベント(定数Event.ENTER_FRAME)のリスナー関数xRotate()では、マウスポインタの座標から計算した水平方向の回転をMatrix3D.prependRotation()メソッドによりMatrix3Dオブジェクトに加え、forループの処理でMatrix3D.transformVector()で4隅のVector3Dインスタンスの座標を変換しています。2次元平面に透視投影するために、Vector3D.wプロパティに変換比率を設定したうえで、Vector3D.project()メソッドを呼出します。なお、透視投影はVector3D.clone()メソッドにより複製したインスタンスに対して行っています。
→関連項目
「3次元変換行列でインスタンスに複数の変換を加えたい」
スクリプト06-16-01■マウスポインタの位置に応じて水平回転させた3次元座標でワイヤーフレームを描く
// フレームアクション
var nUnit:Number = 50;
var nSensitivity:Number = 0.2;
var nFocalLength:Number = nUnit * 2;
var mySprite:Sprite = new Sprite();
var myGraphics:Graphics = mySprite.graphics;
var myMatrix3D:Matrix3D = new Matrix3D();
var myVectors:Vector.<Vector3D> = new Vector.<Vector3D>(); // Vectorインスタンスの生成
mySprite.x = stage.stageWidth / 2;
mySprite.y = stage.stageHeight / 2;
// 4隅の座標をVector3DオブジェクトとしてVectorインスタンスに納める
myVectors.push(new Vector3D(nUnit, nUnit, 0));
myVectors.push(new Vector3D(nUnit, -nUnit, 0));
myVectors.push(new Vector3D(-nUnit, -nUnit, 0));
myVectors.push(new Vector3D(-nUnit, nUnit, 0));
addChild(mySprite);
addEventListener(Event.ENTER_FRAME, xRotate);
function xRotate(eventObject:Event):void {
var i:uint;
var myVector3D:Vector3D;
var projectedVectors:Vector.<Vector3D> = new Vector.<Vector3D>();
var nLength:uint = myVectors.length;
myMatrix3D.prependRotation(mySprite.mouseX * nSensitivity, Vector3D.Y_AXIS);
for (i = 0; i<nLength; i++) { // 4隅のVector3Dインスタンスを取出して処理
myVector3D = myVectors[i];
myVector3D = myMatrix3D.transformVector(myVector3D); // 回転の変換を適用
myVector3D = myVector3D.clone(); // インスタンスを複製
// 透視投影の変換比率をVector3D.wプロパティに設定
myVector3D.w = (nFocalLength + myVector3D.z)/nFocalLength;
myVector3D.project(); // 透視投影
projectedVectors.push(myVector3D);
}
myGraphics.clear();
myGraphics.lineStyle(2, 0);
myGraphics.moveTo(projectedVectors[nLength -1].x, projectedVectors[nLength -1].y);
for (i = 0; i<nLength; i++) { // 透視投影されたVector3Dインスタンスから線描
myVector3D = projectedVectors[i];
myGraphics.lineTo(myVector3D.x, myVector3D.y);
}
}
|
Spriteインスタンスへの線描については、前述「直線を描きたい」をお読みください。
→関連項目
「直線を描きたい」
作成者: 野中文雄
ドラフト作成: 2009年7月2日