赞
踩
AxisAlignedBoundingBox、 BoundingRectangle、 BoundingSphere、 和OrientedBoundingBox
BoundingRectangle
由角、宽度和高度构成的包围框。
虽然是盒子有高度,但它主要用于二维点集、矩形的包围盒创建,高度可以任意指定,无法包围空间上z值不同的点。
BoundingSphere
有中心和半径的包围球。
包围球又很多方法,文档比较详细,本文主要讨论包围盒的显示,故不作太多说明。
AxisAlignedBoundingBox
从沿x、y和z轴的最小和最大点创建AxisAlignedBoundingBox的实例。
参数分别是center、maximum 、minimum
分别表示包围盒中心、最大位置点、最小位置点
OrientedBoundingBox
创建一个OrientedBoundingBox实例。 在许多情况下,它可以提供比BoundingSphere或AxisAlignedBoundingBox更紧密的(tighter)包围盒。 一个物体的OrientedBoundingBox是一个封闭的、凸的长方体。
参数是center、halfAxes
分别表示包围盒中心点、仿射矩阵。
分别采用轴向包围盒AxisAlignedBoundingBox
和朝向包围盒OrientedBoundingBox
,通过一些点集来计算包围盒,最后显示。
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, }) }))
可以看到这种方法显示出的包围盒是正确的。
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()
函数获取长、宽、高
加载出的结果有错误,如下
上述三种显示方法,只有一种是正确的,就是通过在一点上建立空间直角坐标系,将所有点都转化到这个坐标系下,后构建包围盒,进行显示。
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
结果正确
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
结果错误
AxisAlignedBoundingBox
的primitive
、entity
两种加载方法都可以使用,且都加载正确。OrientedBoundingBox
尝试不成功,无论是否将点集转化为特定坐标系与否,总是显示错误,之后有时间弄清楚后再更新,若有大神知道怎么回事,还望告知。(后续研读朝向包围盒计算论文再更新)Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。