应急指挥&污染扩散模拟 | Cesium 多边形动态扩散墙实战教程(附源码)

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

今天咱们来聊聊如何在Cesium中实现一个动态多边形扩散效果,源码请文末自取。

这种效果在应急指挥污染扩散模拟甚至游戏场景中都非常实用。本文将从代码实战出发,带你手撕实现逻辑!

效果预览

🎯 应用场景:当技术遇上业务

  • 应急指挥 :模拟火灾、洪水等灾害的扩散范围,所以不止有辐射圈哦。

  • 环境监测:动态展示污染物扩散趋势。

实现原理

多边形扩散圈效果的核心是通过动态几何形状材质透明度渐变实现,具体分为以下两个部分:

1.1 动态多边形生成

  • 顶点计算 :根据中心点、边数(edge)和当前半径(currentRadius),计算正多边形顶点坐标。每个顶点的位置通过极坐标公式 (x = r*cosθ, y = r*sinθ) 确定,再转换为三维空间坐标。

  • 实时更新 :使用Cesium的CallbackProperty属性,逐帧更新多边形半径和高度,实现扩散动画。当半径超过设定值或高度降为0时,参数重置,形成循环效果。

1.2 材质渐变效果

  • 透明度控制 :在GLSL着色器中,通过fract(st.t)获取纹理坐标的垂直分量,实现从底部到顶部的透明度渐变。公式 material.alpha = color.a * (1.0 - fract(st.t)) * 0.8 使得高度越高越透明。

核心代码分析

动态多边形类 WallRegularDiffuse

javascript 复制代码
// 实时更新多边形顶点(WallPolygonDiffuse.js)
positions: new Cesium.CallbackProperty(() => {
  this._currentRadius += (this._radius * this._speed) / 1000.0;
  this._currentHeight -= (this._height * this._speed) / 1000.0;
  
  // 参数重置逻辑
  if (this._currentRadius > this._radius || this._currentHeight < 0) {
    this._currentRadius = this._minRadius;
    this._currentHeight = this._height;
  }
  
  return this._getPositions(...);
}, false)
  • 功能:每帧更新半径和高度,超出范围后重置,形成循环动画。

  • 关键点CallbackProperty是Cesium的动态属性机制,允许属性值随时间变化。

简单来说,这就是一个**"呼吸循环"**:每次渲染时增大半径、减小高度,超出阈值后重置,形成无限循环的扩散动画。

顶点生成方法 _getPositions

javascript 复制代码
// 扩散正多变形的边数
this._edge = options.edge || 64;
let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(...);
for (let i = 0; i < edge; i++) {
  let angle = (i / edge) * Cesium.Math.TWO_PI;
  let point = new Cesium.Cartesian3(x * currentRadius, y * currentRadius, currentHeight);
  positions.push(Cesium.Matrix4.multiplyByPoint(modelMatrix, point));
}
  • 功能:将局部坐标转换为世界坐标,生成闭合多边形(首尾顶点需要重复)。

自定义材质类 WallDiffuseMaterialProperty

着色器代码(核心)

glsl 复制代码
// 透明度渐变逻辑(WallDiffuseMaterialProperty.js)
material.alpha = color.a * (1.0 - fract(st.t)) * 0.8;
  • 解释st.t表示纹理的垂直坐标(0到1),fract(st.t)取其小数部分,实现从下到上透明度递减。

材质定义

javascript 复制代码
Cesium.Material._materialCache.addMaterial(
  Cesium.Material.WallDiffuseMaterialType, {
    fabric: {
      source: `uniform vec4 color; ...`, // 上述GLSL代码
      uniforms: { color: new Cesium.Color(...) }
    },
    translucent: true // 启用透明度
  }
);
  • 功能:将自定义材质注册到Cesium材质系统,供实体调用。

关键参数说明

参数名 作用
edge 控制多边形的边数(>=3)
speed 扩散速度(值越大动画越快)
radius/height 最大扩散半径和初始高度
minRadius 重置时的最小半径(循环起点)

总结

通过结合Cesium的动态属性机制和自定义着色器,我们实现了多边形扩散圈这一复杂视觉效果。此方案可扩展应用于雷达扫描、灾害范围模拟等场景。

核心思想是动态几何+材质控制,大家也可调整参数或修改着色器代码实现更多变种效果。

最后

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

【预览地址】tingyuxuan2302.github.io/cesium-vue3...

如果开源对您有帮助,希望可以给一个star,鼓励我们开源更多!

不会Cesium的基础,也很难做出更高级的效果,所以可以了解下不浪的教程《Cesium从入门到实战》将Cesium的知识点进行串联,让不了解Cesium的小伙伴拥有一个完整的学习路线,并最终完成一个智慧城市的完整项目,课程也在不断更新迭代中,想了解+作者:brown_7778(备注来意)。
有需要进可视化&Webgis交流群可以加我:brown_7778(备注来意)。

相关推荐
NaZiMeKiY1 小时前
HTML5前端第二章节
前端·html·html5
天若有情6731 小时前
深入浅出:HTML 中 <a> 标签嵌入链接教程
前端·html
烂蜻蜓1 小时前
HTML 样式之 CSS 全面解析
前端·css·html
冬冬小圆帽1 小时前
Webpack 优化深度解析:从构建性能到输出优化的全面指南
前端·webpack·node.js
大龄大专大前端3 小时前
JavaScript闭包的认识/应用/原理
前端·javascript·ecmascript 6
字节源流3 小时前
【SpringMVC】常用注解:@SessionAttributes
java·服务器·前端
肥肠可耐的西西公主3 小时前
前端(vue)学习笔记(CLASS 4):组件组成部分与通信
前端·vue.js·学习
烛阴3 小时前
JavaScript 函数绑定:从入门到精通,解锁你的代码超能力!
前端·javascript
泫凝3 小时前
使用 WebP 优化 GPU 纹理占用
前端·javascript
magic 2453 小时前
CSS块元素、行内元素、行内块元素详解
前端·css