今回からまた3次元空間の話に戻る。新たに学ぶクラスはVector3Dだ。名前が示すとおり、

Vector3DインスタンスをMatrix3Dオブジェクトで座標変換する
まず、
new Vector3D(x座標, y座標, z座標)
Vector3Dインスタンスも、
Matrix3Dオブジェクト.transformVector(Vector3Dオブジェクト)
たとえば、
var myVector3D:Vector3D = new Vector3D(100, 0, 0);
var myMatrix3D:Matrix3D = new Matrix3D();
myMatrix3D.prependRotation(90, Vector3D.Y_AXIS);
trace(myMatrix3D.transformVector(myVector3D));
変換されたVector3Dインスタンスの座標情報が、
Vector3D(6.12323420998628e-15, 0, -100)
なお、
![図1 変換されたVector3Dインスタンスの座標情報が[出力]される 図1 変換されたVector3Dインスタンスの座標情報が[出力]される](/assets/images/dev/serial/01/as3/0042/thumb/TH800_Gihyo110101-001.gif)
![図1 変換されたVector3Dインスタンスの座標情報が[出力]される 図1 変換されたVector3Dインスタンスの座標情報が[出力]される](/assets/images/dev/serial/01/as3/0042/thumb/TH400_Gihyo110101-002.gif)
さて、
1.23e-4 = 1.23×10-4 = 0.000123
Spriteインスタンスに直線を描く
3次元空間座標を行列変換しただけでは、
直線の描き方は、
Graphicsオブジェクト.lineStyle(太さ、カラー, アルファ)
Graphicsオブジェクト.moveTo(x座標, y座標)
Graphicsオブジェクト.lineTo(x座標, y座標)
![図2 [線ツール]と[プロパティ]インスペクタ 図2 [線ツール]と[プロパティ]インスペクタ](/assets/images/dev/serial/01/as3/0042/thumb/TH400_Gihyo110101-004.gif)
ステージ中央に置いたSpriteインスタンスに、
var mySprite:Sprite = new Sprite();
// インスタンスから取出したGraphicsオブジェクトを変数に代入
var myGraphics:Graphics = mySprite.graphics;
mySprite.x = stage.stageWidth / 2;
mySprite.y = stage.stageHeight / 2;
addChild(mySprite);
// Graphicsクラスのメソッドで線描
myGraphics.lineStyle(2, 0x0000FF);
myGraphics.moveTo(-50, -50);
myGraphics.lineTo(50, -50);
myGraphics.lineTo(50, 50);
myGraphics.lineTo(-50, 50);
myGraphics.lineTo(-50, -50);

この座標を線で描く処理は、
でき上がったフレームアクションが、
// フレームアクション
var nUnit:Number = 100 / 2;
var mySprite:Sprite = new Sprite();
var vertices:Array = new Array(); // 座標のPointインスタンスを納める配列生成
var myGraphics:Graphics = mySprite.graphics;
mySprite.x = stage.stageWidth / 2;
mySprite.y = stage.stageHeight / 2;
// xy座標をPointインスタンスにして配列に納める
vertices.push(new Point(-nUnit, -nUnit));
vertices.push(new Point(nUnit, -nUnit));
vertices.push(new Point(nUnit, nUnit));
vertices.push(new Point(-nUnit, nUnit));
addChild(mySprite);
xDrawLines(vertices);
// 配列からPointインスタンスを取出して線描する関数
function xDrawLines(vertices:Array):void {
var nLength:uint = vertices.length;
var myPoint:Point = vertices[nLength - 1];
myGraphics.lineStyle(2, 0x0000FF);
myGraphics.moveTo(myPoint.x, myPoint.y);
for (var i:uint = 0; i < nLength; i++) {
myPoint = vertices[i];
myGraphics.lineTo(myPoint.x, myPoint.y);
}
}
Vectorクラスと3次元空間から2次元平面への変換
いよいよスクリプトに3次元座標の扱いを組込もう。また、
まず、
- Vectorクラスを使うための条件:
- エレメントにひとつのデータ型を定める
- インデックスが連番になる
第1に、
Vectorクラスでひとつとても変わっているのは、
var 変数:Vector.<ベース型> = new Vector.<ベース型>()
備わっているプロパティやメソッドは、
var nUnit:Number = 50;
var vertices:Vector.<Vector3D> = new Vector.<Vector3D>();
vertices.push(new Vector3D(-nUnit, -nUnit, 0));
vertices.push(new Vector3D(nUnit, -nUnit, 0));
vertices.push(new Vector3D(nUnit, nUnit, 0));
vertices.push(new Vector3D(-nUnit, nUnit, 0));
var nLength:uint = vertices.length;
for (var i:uint = 0; i < nLength; i++) {
var myVector3D:Vector3D = vertices[i];
trace(myVector3D);
}
![図4 ベース型がVector3DのVectorインスタンスにエレメントを加えたうえで[出力]する 図4 ベース型がVector3DのVectorインスタンスにエレメントを加えたうえで[出力]する](/assets/images/dev/serial/01/as3/0042/thumb/TH800_Gihyo110101-005.gif)
![図4 ベース型がVector3DのVectorインスタンスにエレメントを加えたうえで[出力]する 図4 ベース型がVector3DのVectorインスタンスにエレメントを加えたうえで[出力]する](/assets/images/dev/serial/01/as3/0042/thumb/TH400_Gihyo110101-006.gif)
つぎに、
そこで定義する関数は、
function xGetVertices2D(myVertices:Vector.<Vector3D>):Vector.<Point> {
var vertices2D:Vector.<Point> = new Vector.<Point>();
var nLength:uint = myVertices.length;
for (var i:uint = 0; i < nLength; i++) {
var myVector3D:Vector3D = myVertices[i];
vertices2D.push(new Point(myVector3D.x, myVector3D.y));
}
return vertices2D;
}
たとえば、


前掲スクリプト1と組合わせて、

フレームアクションは、
// フレームアクション
var nUnit:Number = 100 / 2;
var mySprite:Sprite = new Sprite();
var vertices:Vector.<Vector3D> = new Vector.<Vector3D>();
var myGraphics:Graphics = mySprite.graphics;
mySprite.x = stage.stageWidth / 2;
mySprite.y = stage.stageHeight / 2;
vertices.push(new Vector3D(-nUnit, -nUnit, 0));
vertices.push(new Vector3D(nUnit, -nUnit, 0));
vertices.push(new Vector3D(nUnit, nUnit, 0));
vertices.push(new Vector3D(-nUnit, nUnit, 0));
addChild(mySprite);
var vertices2D:Vector.<Point > = xGetVertices2D(vertices);
xDrawLines(vertices2D);
function xGetVertices2D(myVertices:Vector.<Vector3D>):Vector.<Point> {
var vertices2D:Vector.<Point> = new Vector.<Point>();
var nLength:uint = myVertices.length;
for (var i:uint = 0; i < nLength; i++) {
var myVector3D:Vector3D = myVertices[i];
vertices2D.push(new Point(myVector3D.x, myVector3D.y));
}
return vertices2D;
}
function xDrawLines(vertices2D:Vector.<Point>):void {
var nLength:uint = vertices2D.length;
var myPoint:Point = vertices2D[nLength - 1];
myGraphics.clear();
myGraphics.lineStyle(2, 0x0000FF);
myGraphics.moveTo(myPoint.x, myPoint.y);
for (var i:uint = 0; i < nLength; i++) {
myPoint = vertices2D[i];
myGraphics.lineTo(myPoint.x, myPoint.y);
}
}
マウスポインタの水平位置に応じて3次元座標を水平に回転する
これでようやく前述
function xTransform(myVertices:Vector.<Vector3D>, myRotation:Number):void {
var nLength:uint = myVertices.length;
var myMatrix3D:Matrix3D = new Matrix3D();
myMatrix3D.prependRotation(myRotation, Vector3D.Y_AXIS);
for (var i:int = 0; i<nLength; i++) {
myVertices[i] = myMatrix3D.transformVector(myVertices[i]);
}
}
前掲スクリプト2にこの関数を組込んだうえで、
// フレームアクション
var nUnit:Number = 100 / 2;
var mySprite:Sprite = new Sprite();
var vertices:Vector.<Vector3D> = new Vector.<Vector3D>();
var nDeceleration:Number = 0.3;
var myGraphics:Graphics = mySprite.graphics;
mySprite.x = stage.stageWidth / 2;
mySprite.y = stage.stageHeight / 2;
vertices.push(new Vector3D(-nUnit, -nUnit, 0));
vertices.push(new Vector3D(nUnit, -nUnit, 0));
vertices.push(new Vector3D(nUnit, nUnit, 0));
vertices.push(new Vector3D(-nUnit, nUnit, 0));
addChild(mySprite);
addEventListener(Event.ENTER_FRAME, xRotate);
function xRotate(eventObject:Event):void {
var nRotationY:Number = mySprite.mouseX * nDeceleration;
xTransform(vertices, nRotationY);
var vertices2D:Vector.<Point > = xGetVertices2D(vertices);
xDrawLines(vertices2D);
}
function xTransform(myVertices:Vector.<Vector3D>, myRotation:Number):void {
var nLength:uint = myVertices.length;
var myMatrix3D:Matrix3D = new Matrix3D();
myMatrix3D.prependRotation(myRotation, Vector3D.Y_AXIS);
for (var i:int = 0; i<nLength; i++) {
myVertices[i] = myMatrix3D.transformVector(myVertices[i]);
}
}
function xGetVertices2D(myVertices:Vector.<Vector3D>):Vector.<Point > {
var vertices2D:Vector.<Point> = new Vector.<Point>();
var nLength:uint = myVertices.length;
for (var i:uint = 0; i < nLength; i++) {
var myVector3D:Vector3D = myVertices[i];
vertices2D.push(new Point(myVector3D.x, myVector3D.y));
}
return vertices2D;
}
function xDrawLines(vertices2D:Vector.<Point>):void {
var nLength:uint = vertices2D.length;
var myPoint:Point = vertices2D[nLength - 1];
myGraphics.clear();
myGraphics.lineStyle(2, 0x0000FF);
myGraphics.moveTo(myPoint.x, myPoint.y);
for (var i:uint = 0; i < nLength; i++) {
myPoint = vertices2D[i];
myGraphics.lineTo(myPoint.x, myPoint.y);
}
}
[ムービープレビュー]を確かめると、



今回解説した次のサンプルファイルがダウンロードできます。
- サンプルファイル
(CS5形式/約180KB)