在Cesium中计算动目标姿态是一项关键的任务,特别是在虚拟仿真和地理信息系统中。通过使用Cesium提供的强大的空间计算和可视化功能,可以实现对动目标姿态的高效计算和可视化展示。动态目标姿态的计算涉及到对目标的位置、速度、加速度和旋转等参数的动态变化进行实时更新和推演。借助Cesium的API和文档,开发人员可以利用其内置的数学库和数据可视化功能,构建出精确、流畅的动态目标姿态计算和展示系统。这对于航天、军事模拟、船舶追踪等场景都具有重要的应用意义。
恒歌科技
/10/25
三维场景中,经常需要模拟一些运动的目标,比如行驶中的汽车,飞行中的飞机,在轨运行的卫星等等。单纯的位置移动比较容易实现,但运动姿态(例如汽车的朝向)则需要进行复杂的计算。
如何实现三维场景中动目标姿态的计算?
▼▼▼
坐标系简介
1
球心坐标系
指坐标原点与地心重合,Z轴垂直赤道面,X轴朝向(东经0°,北纬0°),Y轴朝向(东经90°,北纬0°),如图一所示。
图一Cesium球心坐标系
模型坐标系
指建模软件在建模过程中或者在程序构建图元时使用的坐标系。为了方便建模,一般球状物体的原点都在物体中心,游戏角色模型原点一般位于脚部。
获取目标位置
2
在三维场景中加载模型时,一般有两种方法。
方法一
建模时,直接把模型建立在目标位置的世界坐标上。此处,以世界坐标(100,0,0)为例。
利用此方法进行模型绕中心点旋转的操作时,会出现模型沿着世界坐标的原点作半径为100的圆周运动。要想达到正确效果,就必须先把模型移到世界原点并且进行旋转,然后再移回原来位置,这样操作就变得十分麻烦。
方法二
在三维场景中直接加载模型时,模型中心点会与地心重合,也就是说模型坐标(0,0,0)会和球心坐标(0,0,0)点重合。如果要把模型放置到地球表面任意一点,则需要矩阵转换,使模型的顶点坐标转换到地球表面。
P.S. 此种方法最为常用,建议大家使用!
那么,Cesium中是如何把模型放置到地球表面的指定位置处?
Cesium中可以将表示经纬高的坐标点通过Cesium.Cartesian3.fromDegrees(经度,纬度,高度)转换得到对应的世界坐标,然后通过一个四维矩阵对模型进行旋转和平移得到目标位置。
Cesium中提供了多种世界坐标转换为矩阵的接口,不同的转换接口,放置到地球表面模型的姿态角度不同。如图二所示,转换到地球高空某位置的飞机会有各种姿态,其中我们经常用到的“东北天”坐标是中间ClassicalEastNorthUp local Frame所示效果,模型坐标系的X轴朝向正东方向,Y轴朝向正北方向,Z轴朝向垂直于地球表面向上方向。
图二 飞机的各种姿态
图三 “东北天”转换接口
图三中的eastNorthUpToFixedFrame函数是用于处理“东北天”姿态使用的的接口,其中的参数的含义如下:
1)Origin是模型位置的世界坐标,可以通过Cesium.Cartesian3.fromDegrees(经度,纬度,高度)转换得到;
2)ellipsoid为参考的椭球体;
3)result为返回的矩阵,该矩阵中包含了模型的旋转角度与平移距离。
计算目标姿态
3
了解了以上的知识点后,正式开始介绍如何计算动目标姿态。图四是我们模拟的两个时刻飞行中飞机的位置,以此来阐述姿态的计算。
图四 飞行中飞机的位置
图四中两个时刻飞机的姿态都是初始状态,即“东北天”姿态下,headingPitchRoll为(0,0,0),其中时刻一对应位置为“A点”,时刻二对应位置为“B点”。那么,如何计算飞机模型由“A点”朝向“B点”飞行姿态?
从图中可以看出,只要在“A点”给飞机模型一个旋转矩阵M,使飞机在模型坐标系下X轴与AB连线(蓝色发光线)重合,即可实现飞机由A点向B点的飞行效果。因此我们可以先计算出旋转矩阵M,再根据M计算飞机的飞行姿态。
Cesium中为我们提供了一个绕轴旋转的接口,如图五。接口的返回值是一个四元数,将四元数转换成矩阵即可,接口中的参数含义如下:
1)axis是旋转轴;
2)angle是旋转角度的弧度值;
3)result为返回的四元数,该值是绕旋转轴axis旋转angle角度后的四元数的值。
图五
根据图五接口入参的要求,需要正确的计算出旋转轴(axis)和旋转角度(angle)。由于先旋转后平移,和先平移后旋转的效果是完全不一样的,且飞机从模型坐标到地球表面位置转换中经过了旋转和平移(图四接口得到的矩阵变换),因此我们在计算图五接口中的旋转轴和旋转角度时,需要考虑模型已经存在的旋转和平移的影响。
下面使用关键代码说明:
计算模型坐标系下的航向向量
使用相对坐标计算可以减少平移量的影响。首先设时刻一位置为pos1(x1,y1,z1),时刻二位置为pos2(x2,y2,z2),那么得到同一局部坐标系航向向量curAxis=(x2-x1,y2-y1,z2-z1)。
计算模型坐标下航向向量。如上面代码所示,因为从模型坐标到世界坐标经过了旋转,需要还原回去,所以需要获取Cesium.Matrix4.getRotation(Cesium.Transforms.eastNorthUpToFixedFrame(pos1))的逆矩阵,乘以curAxis向量,得到在局部坐标系下的航向向量curAxis。
计算旋转轴和旋转角度
旋转轴可以通过X1向量和运动方向向量叉乘得到。vec1参数为X轴的单位向量,vec2参数为前面计算出来的模型坐标系下的航向向量curAxis。两向量夹角根据公式cosθ=(向量a·向量b)/|向量a|×|向量b|计算出来。向量点乘(向量a·向量b)的值可以用Cesium.Cartesian3.dot(vec1, vec2)计算,向量模值可以用Cesium.Cartesian3.magnitude(vec1)计算。最后用Cesium.Math.acosClamped计算反三角函数值,既夹角的弧度值。
计算姿态角
使用Cesium.Quaternion.fromAxisAngle()接口得到一个四元数,再使用Cesium.HeadingPitchRoll.fromQuaternion()接口计算出每个方向的姿态角。
核心代码如下:
P.S. 因准备时间匆忙,文笔有限,若有阐述不清之处还望包涵。如有更多想了解的知识,请留言告诉我们,更欢迎大家加入FreeX社群进行讨论。
收集不易,本文《计算动目标姿态:Cesium中的实用指南》知识如果对你有帮助,请点赞收藏并留下你的评论。