You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CesiumJS中如何旋转墙体?设置orientation后未生效求解决

问题:CesiumJS中墙体旋转功能无法实现

我尝试通过设置orientation属性来实现墙体旋转,但不清楚问题出在哪里,恳请告知解决方法。

我的代码如下:

const coordinates1 =
       [103.63489648850312,29.78399543240111,103.63494150663065,29.78333590922089,103.635553885046,29.783280635414627,103.63574287140266,29.783196010558108,
        103.63620765390426,29.783160361213504,103.63656871959176,29.783150670758086,103.63687253364753,29.783122359794692,
        103.63703689114861,29.783125411914874,103.63722310083804,29.78321706433821,103.63729821843017,29.78323540821292,
        103.63693308223041,29.783680207069843,103.63629639553365,29.78406369054707,103.635696188705 ,29.7842438403505,
        103.63532376388201,29.784315674969854,103.63487784803836,29.7843448268703,103.63489648850312,29.78399543240111]

let heading = Cesium.Math.toRadians(90)
let pitch = Cesium.Math.toRadians(45)
let roll = Cesium.Math.toRadians(45)
let hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll)
var center = Cesium.Cartesian3.fromDegrees(103.63722310083804,29.78321706433821)
let orientation = Cesium.Transforms.headingPitchRollQuaternion(center, hpr)

var maximumHeights = new Array(coordinates1.length).fill(16);
var minimumHeights = new Array(coordinates1.length).fill(0);
var wall =  viewer.entities.add({
    positions: center,
    orientation:orientation,
    wall:{
        positions: Cesium.Cartesian3.fromDegreesArray(coordinates1),
        maximumHeights: maximumHeights,
        minimumHeights: minimumHeights,
        outline:false,
        material : Cesium.Color.BLUE.withAlpha(0.4),
    }
})
console.log(wall)

原因分析

Cesium中Entity的orientation属性仅对**模型(Model)、广告牌(Billboard)、标签(Label)**等具有"朝向"属性的组件生效,Wall组件不支持通过orientation直接旋转。因为Wall的位置是基于绝对地理坐标定义的,不会继承Entity的orientation变换逻辑。

解决方法

手动将墙体的所有坐标点围绕指定中心点进行旋转变换,生成新的坐标后再赋值给Wall的positions。具体步骤如下:

  1. 编写坐标旋转函数,实现点围绕中心点的旋转变换;
  2. 将原始经纬度坐标转换为笛卡尔坐标数组;
  3. 对坐标数组执行旋转操作;
  4. 使用旋转后的坐标创建Wall。

修改后的完整代码

const coordinates1 =
       [103.63489648850312,29.78399543240111,103.63494150663065,29.78333590922089,103.635553885046,29.783280635414627,103.63574287140266,29.783196010558108,
        103.63620765390426,29.783160361213504,103.63656871959176,29.783150670758086,103.63687253364753,29.783122359794692,
        103.63703689114861,29.783125411914874,103.63722310083804,29.78321706433821,103.63729821843017,29.78323540821292,
        103.63693308223041,29.783680207069843,103.63629639553365,29.78406369054707,103.635696188705 ,29.7842438403505,
        103.63532376388201,29.784315674969854,103.63487784803836,29.7843448268703,103.63489648850312,29.78399543240111]

// 旋转函数:将点数组围绕中心点按指定HeadingPitchRoll旋转
function rotatePointsAroundCenter(points, center, hpr) {
    // 根据HPR创建旋转四元数
    const rotationQuaternion = Cesium.Transforms.headingPitchRollQuaternion(Cesium.Cartesian3.ZERO, hpr);
    const rotatedPoints = [];

    for (const point of points) {
        // 计算点相对于中心点的偏移向量
        const offset = Cesium.Cartesian3.subtract(point, center, new Cesium.Cartesian3());
        // 旋转偏移向量
        const rotatedOffset = Cesium.Quaternion.multiplyByVector(rotationQuaternion, offset, new Cesium.Cartesian3());
        // 计算旋转后的点坐标
        const rotatedPoint = Cesium.Cartesian3.add(center, rotatedOffset, new Cesium.Cartesian3());
        rotatedPoints.push(rotatedPoint);
    }
    return rotatedPoints;
}

// 配置旋转参数
let heading = Cesium.Math.toRadians(90);
let pitch = Cesium.Math.toRadians(45);
let roll = Cesium.Math.toRadians(45);
let hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
const center = Cesium.Cartesian3.fromDegrees(103.63722310083804,29.78321706433821);

// 转换原始坐标为笛卡尔数组并旋转
const originalPositions = Cesium.Cartesian3.fromDegreesArray(coordinates1);
const rotatedPositions = rotatePointsAroundCenter(originalPositions, center, hpr);

// 创建墙体
const maximumHeights = new Array(originalPositions.length).fill(16);
const minimumHeights = new Array(originalPositions.length).fill(0);
const wall = viewer.entities.add({
    wall: {
        positions: rotatedPositions,
        maximumHeights: maximumHeights,
        minimumHeights: minimumHeights,
        outline: false,
        material: Cesium.Color.BLUE.withAlpha(0.4),
    }
});

关键说明

  • 旋转函数通过计算每个点相对于中心点的偏移向量,对偏移向量执行旋转后再叠加回中心点,实现整体旋转效果;
  • 移除了原代码中无效的positions和orientation属性,因为它们对Wall组件不起作用;
  • 注意maximumHeights和minimumHeights的长度要与旋转后的坐标数组长度一致(原代码中coordinates1是经纬度对的数组,长度是坐标点数的2倍,这里修正为与笛卡尔坐标数组长度匹配)。

内容的提问来源于stack exchange,提问作者Summer Llyed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 19:39:51