cesium包围盒的创建和显示尝试

cesium包围盒的创建和显示尝试

0. 包围盒的概念

  1. 点集、面、实体都可以用一个长方形将它们包围起来,应用方面有很多,比如碰撞检测,最大最小边界确定。
  2. cesium提供了两种三种包围盒、一种包围球的计算方式,分别是AxisAlignedBoundingBox、 BoundingRectangle、 BoundingSphere、 和OrientedBoundingBox

1. cesium中的包围盒的简单解释

  1. BoundingRectangle

由角、宽度和高度构成的包围框。

虽然是盒子有高度,但它主要用于二维点集、矩形的包围盒创建,高度可以任意指定,无法包围空间上z值不同的点。

  1. BoundingSphere

有中心和半径的包围球。

包围球又很多方法,文档比较详细,本文主要讨论包围盒的显示,故不作太多说明。

  1. AxisAlignedBoundingBox

从沿x、y和z轴的最小和最大点创建AxisAlignedBoundingBox的实例。

参数分别是center、maximum 、minimum分别表示包围盒中心、最大位置点、最小位置点

  1. OrientedBoundingBox

创建一个OrientedBoundingBox实例。 在许多情况下,它可以提供比BoundingSphere或AxisAlignedBoundingBox更紧密的(tighter)包围盒。 一个物体的OrientedBoundingBox是一个封闭的、凸的长方体。

参数是center、halfAxes分别表示包围盒中心点、仿射矩阵。

2. 包围盒显示

分别采用轴向包围盒AxisAlignedBoundingBox和朝向包围盒OrientedBoundingBox,通过一些点集来计算包围盒,最后显示。

  1. 采用 AxisAlignedBoundingBox,利用viewer.entities.add()添加实体
let boundingBox = Cesium.AxisAlignedBoundingBox.fromPoints(this._positions, new Cesium.AxisAlignedBoundingBox()) 
let dimensions = Cesium.Cartesian3.subtract(boundingBox.maximum, boundingBox.minimum, new Cesium.Cartesian3())
this._delegate.position = center;
this._delegate.box.dimensions = dimensions;
this.overlayLayer.add(this.delegate)
        

其中_positions是世界笛卡尔坐标,最后显示的包围盒存在问题,不能完全包围,如下图

在这里插入图片描述
2. 采用 AxisAlignedBoundingBox,利用scene.primitives.add()添加实体,利用Cesium.BoxGeometry.fromAxisAlignedBoundingBox()函数将AxisAlignedBoundingBox转化为BoxGeometry
核心代码是:

let ms = this._buildModelCoor(this._positions[0])
let m = this._xlBox._modelMatrix
let boundingBox = Cesium.AxisAlignedBoundingBox.fromPoints(ms, new Cesium.AxisAlignedBoundingBox()) 
let newBox = Cesium.BoxGeometry.fromAxisAlignedBoundingBox(boundingBox);
viewer.scene.primitives.add(new Cesium.Primitive({
    geometryInstances : new Cesium.GeometryInstance({
        geometry :newBox,
        modelMatrix : m,
        id : 'ellipsoid',
        attributes : {
          color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUA.withAlpha(0.5))
        },
    }),
    appearance : new Cesium.PerInstanceColorAppearance({
        flat : true,
    })
}))

在这里插入图片描述
可以看到这种方法显示出的包围盒是正确的。

  1. OrientedBoundingBox使用viewer.entities.add()添加
    有一个问题想了好久,类OrientedBoundingBox中的halfAxes的理解,应该是包围盒的长度、宽度、和高度。
    但是halfAxes又是一个3*3的矩阵,我的理解是矩阵的每一列的平方根就是包围盒每一段的边长
    主要显示代码:

this.boundingBox = Cesium.OrientedBoundingBox.fromPoints(this._positions, Cesium.OrientedBoundingBox());
 let dimensions = Cesium.Matrix3.getScale(this.boundingBox.halfAxes , new Cesium.Cartesian3());
 Cesium.Cartesian3.multiplyByScalar(dimensions, 2 , dimensions);
 let center = this._xlBox.computerWorldPosition(this.boundingBox.center, this._xlBox._modelMatrix)
 this._delegate.position = center;
 this._delegate.box.dimensions = dimensions;
 return this

使用Cesium.Matrix3.getScale()函数获取长、宽、高
加载出的结果有错误,如下

在这里插入图片描述

3. 包围盒显示纠正

上述三种显示方法,只有一种是正确的,就是通过在一点上建立空间直角坐标系,将所有点都转化到这个坐标系下,后构建包围盒,进行显示。

  1. 测试一,AxisAlignedBoundingBox构成包围盒
    加载代码:
let ms = this._buildModelCoor(this._positions[0])
let boundingBox = Cesium.AxisAlignedBoundingBox.fromPoints(ms, new Cesium.AxisAlignedBoundingBox()) 
let dimensions = Cesium.Cartesian3.subtract(boundingBox.maximum, boundingBox.minimum, new Cesium.Cartesian3())
let center = this._xlBox.computerWorldPosition(boundingBox.center, this._xlBox._modelMatrix)
this._delegate.position = center;
this._delegate.box.dimensions = dimensions;
return this

在这里插入图片描述
结果正确

  1. 测试二,OrientedBoundingBox构成包围盒
    加载代码:
let ms = this._buildModelCoor(this._positions[0])
this.boundingBox = Cesium.OrientedBoundingBox.fromPoints(ms, Cesium.OrientedBoundingBox());
let dimensions = Cesium.Matrix3.getScale(this.boundingBox.halfAxes , new Cesium.Cartesian3());
Cesium.Cartesian3.multiplyByScalar(dimensions, 2 , dimensions);
let center = this._xlBox.computerWorldPosition(this.boundingBox.center, this._xlBox._modelMatrix)
this._delegate.position = center;
this._delegate.box.dimensions = dimensions;
return this

在这里插入图片描述
结果错误

4. 结论

  1. 尝试了许多次,需要将包围盒转化成某点的特定坐标系才能正确显示。
  2. AxisAlignedBoundingBoxprimitiveentity两种加载方法都可以使用,且都加载正确。
  3. OrientedBoundingBox尝试不成功,无论是否将点集转化为特定坐标系与否,总是显示错误,之后有时间弄清楚后再更新,若有大神知道怎么回事,还望告知。(后续研读朝向包围盒计算论文再更新)
  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值