Skip to content
Cesium计算模型包围盒中心点

简介

本文将介绍如何使用Cesium计算模型的包围盒中心点,我们将详细解释实现的原理,并提供相应的代码示例。

实现思路

方法一

通过CesiumCesium3DTileset加载模型后,直接通过boundingVolume拿到模型的中心点即可

javascript
        const tileset = await Cesium.Cesium3DTileset.fromUrl(url, {
          skipLevelOfDetail: true,
          baseScreenSpaceError: 1024,
          skipScreenSpaceErrorFactor: 16,
          skipLevels: 1,
          immediatelyLoadDesiredLevelOfDetail: false,
          loadSiblings: false,
          cullWithChildrenBounds: true,
        });
        const root = tileset.root;
        const boundingVolume = root.boundingVolume;
        const modelCenter = boundingVolume.boundingSphere.center;
        const halfAxes = boundingVolume.boundingVolume.halfAxes;
        const wgs84Cartographic =
          Cesium.Cartographic.fromCartesian(modelCenter);
        const lon = Cesium.Math.toDegrees(wgs84Cartographic.longitude);
        const lat = Cesium.Math.toDegrees(wgs84Cartographic.latitude);
        const height = wgs84Cartographic.height;
        dataObj.lon = lon;
        dataObj.lat = lat;
        dataObj.height = height;
        viewer.entities.add({
            position: modelCenter,
            point: {
              pixelSize: 20,
              color: Cesium.Color.YELLOW,
            },
          });

方法二

这个是网上的方法,然后我把计算模型方向及旋转角度的方法也加到里面去了,懒得删了,就丢一起吧

{% link Cesium 解析3DTile的包围盒中心点坐标,WebGiser,https://www.jianshu.com/p/6cd91d922920 %}

javascript
      // 解析包围盒中心点坐标,以及计算模型的方向旋转角度
      fetch(url)
        .then((res) => res.json())
        .then((response) => {
          console.log("response", response);
          let root = response.root;
          let boundingVolume = root.boundingVolume;
          let modelCenter;
          if (boundingVolume.hasOwnProperty("box")) {
            let x = boundingVolume.box[0];
            let y = boundingVolume.box[1];
            let z = boundingVolume.box[2];
            let w = 1;
            modelCenter = new Cesium.Cartesian4(x, y, z, w);
          } else if (boundingVolume.hasOwnProperty("region")) {
            let x = (boundingVolume.region[0] + boundingVolume.region[2]) / 2;
            let y = (boundingVolume.region[1] + boundingVolume.region[3]) / 2;
            let z = (boundingVolume.region[4] + boundingVolume.region[5]) / 2;
            let cartographic = new Cesium.Cartographic(x, y, z);
            let wgs84Cartesian3 = Cesium.Cartographic.toCartesian(cartographic);
            modelCenter = new Cesium.Cartesian4(
              wgs84Cartesian3.x,
              wgs84Cartesian3.y,
              wgs84Cartesian3.z,
              1
            );
          } else if (boundingVolume.hasOwnProperty("sphere")) {
            let x = boundingVolume.sphere[0];
            let y = boundingVolume.sphere[1];
            let z = boundingVolume.sphere[2];
            let w = 1;
            modelCenter = new Cesium.Cartesian4(x, y, z, w);
          }
          // 是否有转换矩阵
          if (root.hasOwnProperty("transform")) {
            let transform = root.transform;
            let matrix4 = Cesium.Matrix4.fromColumnMajorArray(transform);
            let wgs84Cartesian4 = Cesium.Matrix4.multiplyByVector(
              matrix4,
              modelCenter,
              new Cesium.Cartesian4()
            );
            let wgs84Cartesian3 =
              Cesium.Cartesian3.fromCartesian4(wgs84Cartesian4);
            let wgs84Cartographic =
              Cesium.Cartographic.fromCartesian(wgs84Cartesian3);
            let lon = Cesium.Math.toDegrees(wgs84Cartographic.longitude);
            let lat = Cesium.Math.toDegrees(wgs84Cartographic.latitude);
            let height = wgs84Cartographic.height;
            dataObj.lon = lon;
            dataObj.lat = lat;
            dataObj.height = height;
            gui.add(dataObj, "lon", dataObj.lon);
            gui.add(dataObj, "lat", dataObj.lat);
            gui.add(dataObj, "height", dataObj.height);
            //-----------------计算模型欧拉角----------------
            const m1 = Cesium.Transforms.eastNorthUpToFixedFrame(
              Cesium.Matrix4.getTranslation(
                tileset.root.transform,
                new Cesium.Cartesian3()
              ),
              Cesium.Ellipsoid.WGS84,
              new Cesium.Matrix4()
            );
            const m3 = Cesium.Matrix4.multiply(
              Cesium.Matrix4.inverse(m1, new Cesium.Matrix4()),
              tileset.root.transform,
              new Cesium.Matrix4()
            );
            const mat3 = Cesium.Matrix4.getMatrix3(m3, new Cesium.Matrix3());
            const q = Cesium.Quaternion.fromRotationMatrix(mat3);
            const hpr = Cesium.HeadingPitchRoll.fromQuaternion(q);

            // 获取模型的heading、pitch、roll
            const heading = Cesium.Math.toDegrees(hpr.heading);
            const pitch = Cesium.Math.toDegrees(hpr.pitch);
            const roll = Cesium.Math.toDegrees(hpr.roll);
            dataObj.heading = heading;
            dataObj.pitch = pitch;
            dataObj.roll = roll;
            gui.add(dataObj, "heading", dataObj.heading);
            gui.add(dataObj, "pitch", dataObj.pitch);
            gui.add(dataObj, "roll", dataObj.roll);
            console.log('dataObj',dataObj)
             //-----------------计算模型欧拉角----------------

          } else {
            let wgs84Cartographic =
              Cesium.Cartographic.fromCartesian(modelCenter);
            let lon = Cesium.Math.toDegrees(wgs84Cartographic.longitude);
            let lat = Cesium.Math.toDegrees(wgs84Cartographic.latitude);
            let height = wgs84Cartographic.height;
            dataObj.lon = lon;
            dataObj.lat = lat;
            dataObj.height = height;
            gui.add(dataObj, "lon", dataObj.lon);
            gui.add(dataObj, "lat", dataObj.lat);
            gui.add(dataObj, "height", dataObj.height);
          }
        });

实现效果

效果如下图所示 image.png

Updated at: