Skip to content

Cesium黑科技,360°立体雷达扫描效果,科技感直接拉满!源码拷走直接复用

之前创建的园区还缺一些炫酷的效果,今天增加了一个立体雷达扫描效果,在三维上实现雷达扫描,看起来效果还是相当不错的。

数字孪生、智慧安防、园区监控、军事仿真、三维大屏场景中,立体雷达扫描效果绝对是最吸睛功能!

旋转的扇形扫描面 + 半球预警范围 + 动态绿色雷达光效,瞬间让你的三维场景拥有科幻级效果

实现方案

基于Cesium原生API,由半球预警范围体(Ellipsoid)和动态扇形扫描面(Wall)两部分组成。

Cesium.Transforms.eastNorthUpToFixedFrame:东北天坐标系转换,实现扇形点位计算。

通过数学计算实时生成扇形扫描路径点,随旋转角度更新,CallbackProperty:动态更新Wall扫描面点位。

使用Cesium Clock的Clock.onTick事件驱动角度自增,实现360°循环旋转。

实现代码

javascript
// 创建/移除 3D立体雷达扫描效果
const createRadarScanEffect = () => {
    isShowRadarScan.value = !isShowRadarScan.value;

    if (isShowRadarScan.value) {
        // 先清除已有雷达
        if (radarScanRef.value) {
            if (radarScanRef.value.tickListener) {
                radarScanRef.value.tickListener();
            }
            if (cesiumViewer.value && radarScanRef.value.id) {
                const entity = cesiumViewer.value.entities.getById(radarScanRef.value.id);
                if (entity) {
                    cesiumViewer.value.entities.remove(entity);
                }
            }
            radarScanRef.value = null;
        }

        // ==================== 雷达配置参数 ====================
        const radarId = 'radar-scan-effect';
        const shortwaveRange = 140;        // 雷达半径(米)
        const longitude = 117.105266;      // 雷达中心点经度
        const latitude = 36.437533;        // 雷达中心点纬度
        const position = Cesium.Cartesian3.fromDegrees(longitude, latitude);
        let heading = 0;                   // 初始旋转角度

        // 计算雷达扇形扫描点(核心算法)
        const 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);
            
            // 生成扇形路径点
            let positionArr = [];
            positionArr.push(x1, y1, 0);
            var radiusDist = Cesium.Cartesian3.distance(
                Cesium.Cartesian3.fromDegrees(x1, y1),
                Cesium.Cartesian3.fromDegrees(x2, y2)
            );
            for (let i = 0; i <= 90; i++) {
                let h = radiusDist * 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, y, h);
            }
            return positionArr;
        };
        
        let positionArr = calcPoints(longitude, latitude, shortwaveRange, heading);
        
        // 添加雷达实体
        const entity = cesiumViewer.value.entities.add({
            id: radarId,
            position: position,
            // 扇形动态扫描面
            wall: {
                positions: new Cesium.CallbackProperty(() => {
                    return Cesium.Cartesian3.fromDegreesArrayHeights(positionArr);
                }, false),
                material: new Cesium.Color.fromCssColorString("#3cf80a94"),
                distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0.0, 10.5e6),
            },
            // 半球预警范围
            ellipsoid: {
                radii: new Cesium.Cartesian3(shortwaveRange, shortwaveRange, shortwaveRange),
                maximumCone: Cesium.Math.toRadians(90),
                material: new Cesium.Color.fromCssColorString("#3cf80a94"),
                outline: true,
                outlineColor: new Cesium.Color.fromCssColorString("#3cf80a94"),
                outlineWidth: 1,
                stackPartitions: 40,
                slicePartitions: 40,
                distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0.0, 10.5e6),
            },
        });
        
        // 雷达旋转动画(onTick实时更新)
        const tickListener = cesiumViewer.value.clock.onTick.addEventListener(() => {
            heading += 1.0; // 旋转速度
            positionArr = calcPoints(longitude, latitude, shortwaveRange, heading);
        });
        
        // 保存引用
        radarScanRef.value = {
            id: radarId,
            entity: entity,
            tickListener: tickListener,
            heading: heading,
            positionArr: positionArr,
            longitude: longitude,
            latitude: latitude,
            shortwaveRange: shortwaveRange
        };
        
        console.log('✅ 雷达扫描效果创建成功!');
    } else {
        // 关闭雷达效果
        if (radarScanRef.value) {
            if (radarScanRef.value.tickListener) {
                radarScanRef.value.tickListener();
            }
            if (cesiumViewer.value && radarScanRef.value.id) {
                const entity = cesiumViewer.value.entities.getById(radarScanRef.value.id);
                if (entity) {
                    cesiumViewer.value.entities.remove(entity);
                }
            }
            radarScanRef.value = null;
            console.log('✅ 雷达扫描已移除');
        }
    }

    // 强制渲染
    if (cesiumViewer.value && cesiumViewer.value.scene) {
        cesiumViewer.value.scene.requestRender();
    }
};

总结

基于Cesium原生API实现了360°旋转的3D立体雷达扫描效果,通过半球范围体与动态扇形扫描面结合,展示出3D雷达的视觉效果。

效果看起来还是相当不错的,用在大屏上还是相当唬人的。