开源!让二维变成三维立体雷达,提升项目的颜值

大家好,我是日拱一卒的攻城师不浪,致力于前沿科技探索,摸索小而美工作室,这是2025年输出的第42/100篇原创文章。

效果预览

www.bilibili.com/video/BV1L7...

前言

之前我们分享的都是平面雷达,总是感觉缺少一点立体感,或者说是科技感。

那今天我们就来聊聊如何在Cesium中实现一个立体的雷达扫描效果。

应用场景

立体雷达特效常见于以下应用场景:

  1. 军事指挥系统 :显示雷达站的探测覆盖范围,这个在军工项目中基本上是必不可少的功能了
  1. 通信网络规划:可视化信号基站的覆盖区域
  2. 智慧城市:展示特定设施的服务覆盖区域
  3. 气象预报:显示气象雷达的探测范围

原理分析

这个雷达扫描效果的实现主要涉及以下几个技术要点:

  1. 几何体构建 :使用Cesium实体系统 创建半圆球体立体墙体

  2. 动态更新 :通过Clock.onTick监听事件驱动扫描动画

  3. 坐标转换:在地理坐标和笛卡尔坐标间进行转换

  4. 数学计算:使用三角函数计算扫描扇区的点位

核心思路是通过不断更新墙体的位置来实现扫描动画,同时保持球体不变以表示覆盖范围。

代码详解

1. 球体和立体墙创建

javascript 复制代码
addEntities() {
    let entity = this.viewer.entities.add({
      id: this.id,
      position: this.position,
      // 立体墙
      wall: {
        positions: new Cesium.CallbackProperty(() => {
          return Cesium.Cartesian3.fromDegreesArrayHeights(this.positionArr);
        }, false),
        material: new Cesium.Color.fromCssColorString("#00dcff82"),
        distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
          0.0,
          10.5e6
        ),
      },
      // 球体
      ellipsoid: {
        radii: new Cesium.Cartesian3(
          this.shortwaveRange,
          this.shortwaveRange,
          this.shortwaveRange
        ),
        maximumCone: Cesium.Math.toRadians(90),
        material: new Cesium.Color.fromCssColorString("#00dcff82"),
        outline: true,
        outlineColor: new Cesium.Color.fromCssColorString("#00dcff82"),
        outlineWidth: 1,
        distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
          0.0,
          10.5e6
        ),
      },
    });
  }

这个方法创建了两个关键几何体:

  • wall:一个墙体,用于表示扫描的扇区,它的位置通过CallbackProperty动态更新

  • ellipsoid:一个球体,表示雷达的覆盖范围

几个关键参数:

  • shortwaveRange:雷达的覆盖半径

  • position:雷达所在的位置(经度、纬度)

两者都使用了半透明的青色材质#00dcff82,增强了科技感。

2. 动画实现

javascript 复制代码
addPostRender() {
  this.tickListener = this.viewer.clock.onTick.addEventListener(() => {
    this.heading += 1.0; //可调节转动速度
    this.positionArr = this.calcPoints(
      this.longitude,
      this.latitude,
      this.shortwaveRange,
      this.heading
    );
  });
}

动画的核心在于监听Cesium的时钟事件,每一帧更新heading角度,并重新计算扇区的点位数组。

转动速度可以通过调整每帧增加的角度值来控制。

3. 扇区点位计算

javascript 复制代码
calcPoints(x1, y1, radius, heading) {
  var m = Cesium.Transforms.eastNorthUpToFixedFrame(
    Cesium.Cartesian3.fromDegrees(x1, y1)
  );
  var rx = radius * Math.cos((heading * Math.PI) / 180.0);
  var ry = radius * Math.sin((heading * Math.PI) / 180.0);
  var translation = Cesium.Cartesian3.fromElements(rx, ry, 0);
  var d = Cesium.Matrix4.multiplyByPoint(
    m,
    translation,
    new Cesium.Cartesian3()
  );
  var c = Cesium.Cartographic.fromCartesian(d);
  var x2 = Cesium.Math.toDegrees(c.longitude);
  var y2 = Cesium.Math.toDegrees(c.latitude);
  return this.computeCirclularFlight(x1, y1, x2, y2, 0, 90);
}

这个方法是整个效果的核心,它通过以下步骤计算扇区的边缘点:

  1. 创建一个从地理坐标到笛卡尔坐标的转换矩阵

  2. 根据当前heading角度计算出半径方向上的偏移

  3. 将这个偏移应用到矩阵上,得到扇区边缘的一个点

  4. 将这个点转换回地理坐标

  5. 调用computeCirclularFlight方法计算扇区内的所有点

4. 扇区插值计算

javascript 复制代码
computeCirclularFlight(x1, y1, x2, y2, fx, angle) {
  let positionArr = [];
  positionArr.push(x1);
  positionArr.push(y1);
  positionArr.push(0);
  var radius = Cesium.Cartesian3.distance(
    Cesium.Cartesian3.fromDegrees(x1, y1),
    Cesium.Cartesian3.fromDegrees(x2, y2)
  );
  for (let i = fx; i <= fx + angle; i++) {
    let h = radius * Math.sin((i * Math.PI) / 180.0);
    let r = Math.cos((i * Math.PI) / 180.0);
    let x = (x2 - x1) * r + x1;
    let y = (y2 - y1) * r + y1;
    positionArr.push(x);
    positionArr.push(y);
    positionArr.push(h);
  }
  return positionArr;
}

这个方法根据起点和终点计算出一个弧形路径上的所有点。

它首先将起点坐标添加到数组中,然后计算从起点到终点的距离作为半径,接着在指定角度范围内(这里是0到90度)生成一系列点,并设置每个点的高度,形成一个立体的扇区。

5. 资源管理与控制方法

javascript 复制代码
clear() {
  // 停止时钟监听
  if (this.tickListener) {
    this.tickListener();
    this.tickListener = null;
  }

  // 移除实体
  if (this.viewer && this.id) {
    const entity = this.viewer.entities.getById(this.id);
    if (entity) {
      this.viewer.entities.remove(entity);
    }
  }

  // 清理属性
  this.positionArr = [];
  this.heading = 0;
}

类中还提供了多个实用的控制方法:

  • clear():清理资源但保留对象

  • destroy():完全销毁对象

  • stop():暂停动画

  • start():开始动画

  • hide():隐藏雷达效果

  • show():显示雷达效果

这些方法使得雷达效果更易于在不同场景中控制,提高了组件的可复用性。

使用示例

javascript 复制代码
import RadarSolidScan from './RadarSolidScan.js';

// 创建雷达效果
const radar = new RadarSolidScan({
  viewer: viewer, 
  id: 'radar1',  // 唯一标识
  position: [120, 36],
  shortwaveRange: 50000 // 50公里的覆盖范围
});

最后

【完整源码地址】:github.com/tingyuxuan2...

想系统学习Cesium的小伙伴儿,可以了解下不浪的教程《Cesium从入门到实战》,将Cesium的知识点进行串联,让不了解Cesium的小伙伴拥有一个完整的学习路线,并最终完成一个智慧城市的完整项目,课程最近也更新了很多进阶内容,想了解课程大纲,+作者:brown_7778(备注来意)。
有需要进可视化&Webgis交流群可以加我:brown_7778(备注来意)。

相关推荐
gis_rc4 天前
python下shp转3dtiles
python·3d·cesium·3dtiles·数字孪生模型
grasperp5 天前
3DTiles数据切片工具,支持LAS、OBJ、FBX 3DTiles怎么切片?3DTiles切片
cesium·3dtiles·三维gis·3dtiles切片·数据切片
duansamve7 天前
Cesium中实现在地图上移动/旋转点、线、面
cesium
冥界摄政王8 天前
CesiumJS学习第四章 替换指定3D建筑模型
3d·vue·html·webgl·js·cesium
冥界摄政王10 天前
Cesium学习第二章 camera 相机
node.js·html·vue3·js·cesium
冥界摄政王11 天前
Cesium学习第一章 安装下载 基于vue3引入Cesium项目开发
vue·vue3·html5·webgl·cesium
你们瞎搞12 天前
Cesium加载20GB航测影像.tif
前端·cesium·gdal·地图切片
闲云一鹤14 天前
Cesium 使用 Turf 实现坐标点移动(偏移)
前端·gis·cesium
二狗哈14 天前
Cesium快速入门34:3dTile高级样式设置
前端·javascript·算法·3d·webgl·cesium·地图可视化
二狗哈15 天前
Cesium快速入门33:tile3d设置样式
3d·状态模式·webgl·cesium·地图可视化