3D空間にあるオブジェクトの2D座標を得る
Matrix3Dとか三角関数も使わなくても単なるる相似で良いんだ…
レンズ角度(fieldOfView)や消失点(fieldOfView)の変更にも耐えます。
/**
* Copyright Kay ( http://wonderfl.net/user/Kay )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/kGGF
*/
package {
import flash.display.*;
import flash.geom.*;
[SWF(width=465,height=465)]
public class ProjectTest2 extends Sprite {
private const SW:Number = stage.stageWidth;
private const SH:Number = stage.stageHeight;
public function ProjectTest2():void {
//---------------------------------------------------
// 3D表示情報を設定
var proj:PerspectiveProjection = root.transform.perspectiveProjection;
// カメラ角度
proj.fieldOfView = 75;
// 消失点を設定
var disPoint:Point = new Point(100, -50); // カンバス中央から
proj.projectionCenter = new Point(SW/2+disPoint.x,SH/2+disPoint.y);
//---------------------------------------------------
// カンバスをステージ中央に配置
var canvas:Canvas = new Canvas(SW,SH,disPoint);
canvas.x = SW/2;
canvas.y = SH/2;
addChild(canvas);
//---------------------------------------------------
// カンバスのZ軸上に点を表示
var numPoints:int = 10;
for (var i:int = 0; i < numPoints; i++) {
var dot:Dot = new Dot();
dot.x = Math.random()*SW-SW/2;
dot.y = Math.random()*SH-SH/2;
dot.z = Math.random()*200-50;
canvas.addChild(dot);
}
//---------------------------------------------------
// 3D座標から2D座標を取得して点の位置に表示
for (i = 0; i < numPoints; i++) {
var myPoint:Object = canvas.getChildAt(i);
var hint:Hint = new Hint(myPoint,15,0x0000ff);
canvas.addChild(hint);
// 2D座標を計算
var ratio:Number = proj.focalLength/(proj.focalLength+myPoint.z);
if (myPoint.z != 0) {
hint.x = myPoint.x*ratio + disPoint.x - disPoint.x*ratio;
hint.y = myPoint.y*ratio + disPoint.y - disPoint.y*ratio;
} else {
hint.x = myPoint.x*ratio;
hint.y = myPoint.y*ratio;
}
hint.z = 0;
hint.dispVector();
}
}
}
}
import flash.display.*;
import flash.geom.*;
import flash.text.*;
class Canvas extends Sprite {
public function Canvas(w:Number, h:Number, p:Point):void {
graphics.lineStyle(0,0x999999);
// x軸
graphics.moveTo(-w/2,0);
graphics.lineTo(w/2,0);
// y軸
graphics.moveTo(0,-h/2);
graphics.lineTo(0,h/2);
// z軸
graphics.moveTo(-p.x,-p.y);
graphics.lineTo(p.x,p.y);
}
}
class Dot extends Sprite {
public function Dot():void {
graphics.beginFill(0x0066ff);
graphics.drawCircle(0,0,10);
graphics.endFill();
}
}
class Hint extends Sprite {
private var myObject:Object;
private var field:TextField = new TextField();
public function Hint(obj:Object, size:Number=0, nColor:int=0xff0000):void {
myObject = obj;
graphics.lineStyle(0);
graphics.moveTo(0,0);
graphics.lineTo(-size,-size);
field.autoSize = TextFieldAutoSize.LEFT;
field.selectable = false;
field.text = "temp\ntemp";
field.x = -field.height-size;
field.y = -field.height-size;
addChild(field);
}
// 座標を表示
public function dispVector():void {
field.text = '3D(x:'+myObject.x+', y:'+myObject.y+', z:'+myObject.z+")\n2D(x:"+x+', y:'+y+')';
}
}