今天看到 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.然后假定 room 在 scene 的 (10,20,30) 坐标处: var roomM:Matrix3D=new Matrix3D(Vector.<Number>([ 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.<Number>([ 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 |
|