無 乴 2026-01-07 10:34 采纳率: 0%
浏览 2
已结题

cesium开启地形后,垂直线显示错误

cesium 在开启地形之后在每个航点画一条垂直线,然后转动视角垂直线不会基于航点垂直向上,这块该怎么改呢?

img

代码如下:

img

  • 写回答

2条回答 默认 最新

  • 檀越@新空间 2026-01-07 10:35
    关注

    上午好☀️☀️☀️️
    本答案参考通义千问

    你提到的问题是:在 Cesium 中开启地形后,绘制的垂直线(从航点垂直向上)在视角变化时不再保持“垂直”状态。这通常是因为 Cesium 的 地形高度坐标系转换 问题导致的。


    ✅ 问题分析

    在 Cesium 中,当你使用 Cesium.Cartesian3.fromDegrees 创建一个点时,它默认是在 WGS84 椭球体表面 上的点。但如果你开启了地形(terrain),那么这个点实际上可能已经位于地形之上,而不是椭球体上。

    因此,当你从该点向上画一条“垂直线”,如果直接使用 笛卡尔坐标系中的向量(比如 (0, 0, 1)),这条线将不会真正垂直于地面,而是垂直于椭球体,从而导致视角变化时看起来不垂直。


    ✅ 解决方案

    重点部分:要让垂直线始终垂直于地形,需要根据当前地形高度动态计算方向

    ✅ 步骤如下:

    1. 获取当前点的地形高度
    2. 计算从该点向上垂直的单位向量
    3. 使用 Cesium 的 EllipsoidGeodesic 方法来生成垂直线

    ✅ 修改后的代码示例

    // 假设你有一个航点坐标(经度、纬度)
    const point = Cesium.Cartesian3.fromDegrees(longitude, latitude);
    
    // 获取该点的地形高度(注意:需要先加载地形)
    viewer.terrainProvider.requestHeight(point).then(function(height) {
        const cartographic = Cesium.Cartographic.fromCartesian(point);
        cartographic.height = height; // 设置为地形高度
        const pointWithTerrain = Cesium.Cartesian3.fromDegrees(cartographic.longitude, cartographic.latitude, cartographic.height);
    
        // 计算垂直方向(基于地球椭球体)
        const ellipsoid = viewer.scene.globe.ellipsoid;
        const normal = ellipsoid.geodeticSurfaceNormal(pointWithTerrain, new Cesium.Cartesian3());
    
        // 从该点向上延伸一定长度(例如 1000 米)
        const length = 1000; // 单位:米
        const direction = normal.multiplyByScalar(length);
        const end = Cesium.Cartesian3.add(pointWithTerrain, direction, new Cesium.Cartesian3());
    
        // 绘制线
        viewer.entities.add({
            polyline: {
                positions: [pointWithTerrain, end],
                material: Cesium.Color.RED,
                width: 2
            }
        });
    });
    

    ✅ 补充说明

    • 如果你希望垂直线始终与地面真实地形垂直,可以使用 Cesium.CesiumTerrainProvider 提供的高程数据。
    • 在某些情况下,你可以使用 Cesium.Cartesian3.normalize() 来确保方向向量是单位向量。
    • 如果你使用的是 Cesium.Primitive 而不是 Entity,也可以用类似的方法构造线几何。

    ✅ 总结

    | 步骤 | 描述 | |------|------| | 1 | 获取航点的地理坐标 | | 2 | 查询该点的地形高度 | | 3 | 根据椭球体法线计算垂直方向 | | 4 | 使用该方向绘制垂直线 | | 5 | 确保线始终垂直于地形 |


    ✅ 注意事项

    • 地形高度查询需要等待地形加载完成,建议使用 requestHeight 并加上回调。
    • 如果没有启用地形,这段代码仍然有效,只是不会受到地形影响。
    • 如果你使用的是 Cesium.WebMapTileServiceImageryProvider,请确保其支持高程数据。

    如需进一步优化性能或处理多个航点,可以考虑使用 Cesium.PrimitiveCesium.PolylineGeometry 来提高效率。需要我帮你写更高效的版本吗?

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 1月7日
  • 创建了问题 1月7日