1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > cesium 相机跟随

cesium 相机跟随

时间:2022-12-15 21:00:18

相关推荐

cesium 相机跟随

一场大的台风,路径通常很长,可能从靠近赤道的太平洋一直往北吹到东三省。跨度这么大,在三维GIS中,往往不容易看全。如果能够实现相机随动效果,即相机跟随台风步进、移动,就生动许多了。

感觉在cesium中,坐标和视角、相机、view是一个难点,我到现在都搞不清楚。方向(orientation)可以总结一下:

XYZ轴,由负到正,分别对应西东、南北、下上。(cesium是右手)

heading:视场角,观察者(相机?)与地球围绕Y轴转,可以想象为相机向左,地球就向右;反之。

pitch:俯仰角,观察者与地球围绕X轴转;观察者低头,看见地球南极,抬头,看见地球北极。

roll:旋转,观察者与地球围绕Z轴转;可以想象为地球就是一个平面的饼,在围绕圆心在转。

言归正传。一场台风在绘制过程中,每个步骤都有对应的一个坐标值。只要观察者能够跟随这个脚步,从空中俯视,就能观察到每一个步骤的细节。

问题是,如何才能跟随?

相机(camera)的话,有lookAt啦,setView啦,flyTo啦。前面2个在本场景中都用不上,相机不动,光调转角度不行。只有flyTo才会跟随。

但是,flyTo方法,既有viewer.flyTo,又有camera.flyTo。viewer.flyTo,飞向指定坐标点(也就是台风的某个步骤坐标点),该坐标点就会正正好出现在屏幕中央,最符合要求;而camera.flyTo,是相机飞到指定点,如果按照默认值,相机角度是正俯视地球,那么没有问题,指定点也会在屏幕中央;但问题是,相机往往设置了各种倾斜的角度,那么待观察的点就不会在屏幕中央,而是出现在一边,甚至根本看不见!

那我们还犹豫什么,就用viewer.flyTo就好了。不行啊,这个viewer.flyTo,如果当前有数据输出,画面在更新,它不会执行,只有等待一切平静后它才客客气气地执行。这就出现一场台风全部步骤绘制完毕以后,才执行这个viewer.flyTo,黄花菜都凉了。

所以,解决办法还是应该用camera.flyTo。飞到一个合适的坐标点,可以让被观察点(即台风步骤坐标点)出现在屏幕中央。现在的问题是,如何得到这个合适的坐标点,让相机飞过去?

可不可以根据相机的角度,和被观察点的坐标,倒推出这个坐标点,以至于相机来到这里,角度啥的不变,刚好让被观察点出现在屏幕中央?

这个不是方程式,我没有找到计算方法。但是也许可以间接计算。我是这么想的:

台风刚开始的时候,我们先viewer.flyTo台风起点,这时台风起点出现在屏幕中央;

台风前进一步,来到了一个新位置,这时,可以计算它与上一步的位移;

然后我用相机当前位置,加上这个位移,得到一个新的坐标点,这就是那个合适的坐标点

相机飞到这个该死的合适坐标点

以此类推。

代码如下:

//台风开始时,我们飞向起点plet flyEntity = new Cesium.Entity({id : 'flyTmp',position : Cesium.Cartesian3.fromDegrees(p.x,p.y,0),point : {pixelSize : 1,color : Cesium.Color.WHITE.withAlpha(0.0),}});viewer.entities.add(flyEntity);return viewer.flyTo(flyEntity, {offset : {//角度啥都不变heading : viewer.camera.heading,pitch : viewer.camera.pitch,range : HEIGHT}});

//一个台风步骤function step(){let p1 = ... //上一步骤let p2 = ... //当前步骤let cp = viewer.camera.positionCartographic;//当前相机世界坐标let offset = Cesium.Cartesian3.subtract(//两个台风步骤之间的位移Cesium.Cartesian3.fromDegrees(p1.x, p2.y,cp.height), //这个高度必不可少Cesium.Cartesian3.fromDegrees(p1.x, p2.y,cp.height), new Cesium.Cartesian3());let newCameraLoc = Cesium.Cartesian3.add(//新的相机坐标点viewer.camera.position,offset, new Cesium.Cartesian3());viewer.camera.flyTo({destination : newCameraLoc,duration:2,//飞行时间2秒orientation : {heading : viewer.camera.heading,pitch : viewer.camera.pitch,roll : 0.0},complete:function(){//完成后进入下一步;职责链模式step();}});}

当然啦,实际应用过程中,不会步步跟随,而是20步跟随一次,否则系统估计会卡死。

cesium中定位方法使用

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。