非人哉:3d坐标转2d坐标2

来源:百度文库 编辑:九乡新闻网 时间:2024/07/08 19:56:58
今天看到 Matrix3D.transformVectors,终于明白了昨天的问题的解决办法.

假设有一个3d场景 scene, 里面有一个房子 room, 房子里有一个点 p, 3d场景 scene 里有一个摄像机 camera.
scene,room,camera都有各自的坐标系统.
现在的目的是把 p 显示到 camera 的底片 screen 上.

具体步骤就是:首先是把 p 点转换到 scene 的坐标系上描述, 再转换到 camera 的坐标系上描述, 再转换到 screen 上描述.

举例说明:
scene,room,camera都有各自的坐标系统,例如分别叫: sceneM,roomM,cameraM.
sceneM 是最外面的坐标系统,用一个 单位 Matrix3D 对象 表示:
var sceneM:Matrix3D=new Matrix3D(Vector.([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]));
然后假定 room 在 scene 的 (10,20,30) 坐标处:
var roomM:Matrix3D=new Matrix3D(Vector.([1,0,0,0,0,1,0,0,0,0,1,0,10,20,30,1]));
然后假定 p 在 room 的 (40,50,60) 坐标处:
var p:Vector3D=new Vector3D(40,50,60);
然后假定 camera 在 scene 的 (0,0,-1000) 坐标处:
var cameraM:Matrix3D=new Matrix3D(Vector.([1,0,0,0,0,1,0,0,0,0,1,0,0,0,-1000,1]));
p 在 room 中描述是 (40,50,60);
在 scene 中描述,就变成了 (10+40,20+50,30+60);
在 camera 中描述,就变成了 (10+40,20+50,30+60+1000);
如果用 Matrix3D 来转换,就是:
trace("p="+p);//p=Vector3D(40, 50, 60)p=roomM.transformVector(p);trace("p="+p);//p=Vector3D(50, 70, 90)cameraM.invert();p=cameraM.transformVector(p);trace("p="+p);//p=Vector3D(50, 70, 1090)
如果把 roomM 和 cameraM 合起来,可以只调用一次 transformVector :
var m:Matrix3D=roomM.clone();cameraM.invert();m.append(cameraM);//合起来p=m.transformVector(p);trace("p="+p);//p=Vector3D(50, 70, 1090)
然后假定 screen 在 camera 前面 500 处,画图分析:



得知转到 screen 上的点应该是: ((50/1090)*500,(70/1090)*500)
var dScreen:Number=500;var k:Number=dScreen/p.z;var screenX:Number=p.x*k;var screenY:Number=p.y*k;trace(screenX,screenY);//22.93577981651376 32.11009174311927
源文件下载

再来个复杂点的效果,有大,中,小三个立方体,大的在自转,中的在绕着大的转,小的在绕着中的转:


源文件下载:
  cubes.rar