以下完全是一个数学问题。
众所周知,PerspectiveProjection
根据以下公式提供由fieldOfView
和focalLength
的相互依赖值表示的3D视角变换:
focalLength = stageWidth/2 * (cos(fieldOfView/2) / sin(fieldOfView/2)
Illustration by Bjørn Gunnar Staal http://bgstaal.net/blog/wp-content/uploads/2009/06/figure11.jpg
问:如何获取已应用PerspectiveProjection的DisplayObject(上图链接的图像上的多维数据集)的可见屏幕尺寸?
ActionScript 3 lacks functionality for visible bounds of DisplayObject中有关此问题的更全面的说明和说明性代码。
答案 0 :(得分:2)
我想我错过了这一点。
我在ide中进行了一个简单的测试,将3个剪辑放在一起,如下所示:
宽度和高度报告可见3d区域的大小, 正如您在物业检查员中所看到的那样。 您可以像访问
一样简单地访问trace(cube.width + ' by ' + cube.height);
在运行时或使用jsfl:
var doc = fl.getDocumentDOM();
fl.outputPanel.clear();
fl.trace(doc.selection[0].width + ' by ' + doc.selection[0].height);
在authortime中的一个选定剪辑中,在IDE中。
我用一些动作做了类似的测试:
//draw faces
var front:Sprite = drawFace();
var back:Sprite = drawFace();
var left:Sprite = drawFace();
var right:Sprite = drawFace();
var top:Sprite = drawFace();
var bottom:Sprite = drawFace();
//transform faces
front.z = -50;
back.z = 50;
left.x = -50;
right.x = 50;
top.y = -50;
bottom.y = 50;
left.rotationY = right.rotationY = 90;
top.rotationX = bottom.rotationX = 90;
//putem them all together
var cube:Sprite = new Sprite();
cube.addChild(front);
cube.addChild(back);
cube.addChild(left);
cube.addChild(right);
cube.addChild(top);
cube.addChild(bottom);
addChild(cube);
cube.x = stage.stageWidth * .5;
cube.y = stage.stageHeight* .5;
cube.z = -100;
cube.rotationX = cube.rotationY = 30;
trace(cube.width + ' by ' + cube.height);
trace(cube.getBounds(this));
trace(cube.transform.pixelBounds);
this.addEventListener(Event.ENTER_FRAME, loop);
function loop(event:Event):void {
cube.rotationY += 3;
var b:Rectangle = cube.getBounds(this);
graphics.clear();
graphics.lineStyle(1,0x009900);
graphics.drawRect(b.x,b.y,b.width,b.height);
}
function drawFace():Sprite{
var s:Sprite = new Sprite();
s.graphics.beginFill(0x000099,.5);
s.graphics.drawRect(-50,-50,100,100);
s.graphics.endFill();
return s;
}
以下是Programming Actionscript 3.0的修改样本
package {
import flash.display.*
import flash.events.*;
import flash.utils.getTimer;
import flash.geom.*;
public class Triangles extends Sprite {
var x1:Number = -100,y1:Number = -100,z1:Number = 0,t1:Number = 0;
var x2:Number = 100,y2:Number = -100,z2:Number = 0,t2:Number = 0;
var x3:Number = 100,y3:Number = 100,z3:Number = 0,t3:Number = 0;
var x4:Number = -100,y4:Number = 100,z4:Number = 0,t4:Number = 0;
var v1 = new Vector3D(-100,-100,0,0);
var v2 = new Vector3D(100,-100,0,0);
var v3 = new Vector3D(100,100,0,0);
var v4 = new Vector3D(-100,100,0,0);
var focalLength:Number = 200;
var indices:Vector.<int>;
var container:Sprite;
var bitmapData:BitmapData; // texture
var imageLoader:ImageLoader;
public function Triangles():void {
indices = new Vector.<int>();
indices.push(0,1,3, 1,2,3);
container = new Sprite(); // container to draw triangles in
container.x = 200;
container.y = 200;
addChild(container);
imageLoader = new ImageLoader("head.jpg");
imageLoader.addEventListener(Event.COMPLETE, onImageLoaded);
}
function onImageLoaded(event:Event):void {
bitmapData = imageLoader.bitmap.bitmapData;
addEventListener(Event.ENTER_FRAME, rotatePlane);
}
function rotatePlane(event:Event):void {
var ticker = getTimer()/1600;
z2 = z3 = -(z1 = z4 = 100*Math.sin(ticker));
x2 = x3 = -(x1 = x4 = 100*Math.cos(ticker));
v2.z = v3.z = -(v1.z = v4.z = 100*Math.sin(ticker));
v2.x = v3.x = -(v1.x = v4.x = 100*Math.cos(ticker));
t1 = focalLength/(focalLength + z1);
t2 = focalLength/(focalLength + z2);
t3 = focalLength/(focalLength + z3);
t4 = focalLength/(focalLength + z4);
v1.w = focalLength/(focalLength + v1.z);
v2.w = focalLength/(focalLength + v2.z);
v3.w = focalLength/(focalLength + v3.z);
v4.w = focalLength/(focalLength + v4.z);
// determine triangle vertices based on t values
var vertices:Vector.<Number> = new Vector.<Number>();
//vertices.push(x1*t1,y1*t1, x2*t2,y2*t2, x3*t3,y3*t3, x4*t4,y4*t4);
vertices.push(v1.x*v1.w,v1.y*v1.w, v2.x*v2.w,v2.y*v2.w, v3.x*v3.w,v3.y*v3.w, v4.x*v4.w,v4.y*v4.w);
var uvtData:Vector.<Number> = new Vector.<Number>();
uvtData.push(0,0,v1.w, 1,0,v2.w, 1,1,v3.w, 0,1,v4.w);
// draw
container.graphics.clear();
container.graphics.beginBitmapFill(bitmapData);
container.graphics.drawTriangles(vertices, indices, uvtData);
var b:Rectangle = container.transform.pixelBounds;
graphics.clear();
graphics.lineStyle(1,0x009900);
graphics.drawRect(b.x,b.y,b.width,b.height);
}
}
}
pixelBounds在这里工作得很好,但它是一个简单的平面。 pixelBounds在前面的例子中不起作用,但getBounds()似乎工作正常。