基于Cesium的三维视锥绘制与画面模拟
有朋友咨询我cesium下的视锥绘制与监控视角模拟是如何实现的,这里以JavaScript为例,给出一些示例代码。前置条件是,创建了Cesium的Viewer,而为了观察更加真实的模拟视角,可以向地图添加3dtiles。


空间定位参数:共同确定了视锥体的顶点位置及其在三维地球坐标系中的指向。
- Position (Lon, Lat, Alt):视锥体的顶点坐标。它是相机的光心位置,即所有视线的汇聚点。在 Cesium 中通常使用经纬度和高度
- Orientation (Heading, Pitch, Roll):视锥体的*
- Heading:决定水平旋转(左右看)
- Pitch:决定俯仰角度(上下看),通常监控视角为负值。
- Roll:决定相机的侧倾(
镜头几何参数:定义了视锥体截面的形状,模拟了不同焦距镜头产生的视觉效果。
- FOV (Field of View - 视场角):通常指垂直方向的张角。FOV 越大,画面容纳的内容越多(广角镜头);FOV 越小,画面越窄(长焦镜头)。
- Aspect Ratio (宽高比):即视野截面的宽度与高度之比。它必须与你的显示画布(Canvas)或视频流(如 16:9)一致,否则画面会产生拉伸或压缩。
裁剪平面参数:定义了视锥体在视线方向上的有效渲染范围。
- Near (近裁剪面):距离相机的最近可见距离。小于此距离的物体会被切掉(防止相机穿模)。
- Far (远裁剪面):距离相机的最远可见距离。超过此距离的物体将不再渲染,这直接影响渲染性能和地平线的可见度。
绘制流程首先通过 Cesium.Cartesian3.fromDegrees 将经纬度高度转换为空间位置,随后利用 HeadingPitchRoll 结合 -90 度的坐标系偏移校准生成四元数,以确定视锥在地球表面的精确指向。
接着实例化 PerspectiveFrustum 来定义透视矩阵的核心属性(如张角、宽高比及远近平面),并基于此数学模型分别创建 FrustumGeometry(填充体)和 FrustumOutlineGeometry(轮廓线)两个几何实例。
最后,通过设置 ColorGeometryInstanceAttribute 定义颜色与透明度,将实例封装进 Primitive 中并同步添加到场景集合 viewer.scene.primitives,从而在三维空间中渲染出一个代表相机监控范围的半透明四棱台。
给出实现绘制视锥的代码。
1 | /** |
在你的主逻辑文件中,直接传入坐标和旋转参数:
1 | // 假设你已经初始化了 viewer |
模拟流程首先根据传感器坐标设定相机的 destination 目标位置,随后调用 viewer.camera.flyTo 并传入原始的航向角(Heading)与俯仰角(Pitch),启动平滑飞行过渡以对准观察方向。
在相机飞抵指定点后,最关键的一步是手动覆盖 viewer.camera.frustum 属性,通过 new Cesium.PerspectiveFrustum 强制修改相机的投影矩阵。通过同步垂直视场角(fov)、画布宽高比(aspectRatio)以及远近裁剪面,使当前屏幕显示的渲染画面与之前在场景中绘制的红色视锥几何体在数学投影上完全重合。
给出模拟视锥视角的代码:
1 | /** |