OBB碰撞检测算法

备注参考不少网友的观点

OBB包围盒

OBB(Oriented Bounding Box)包围盒也被称作有向包围盒或定向包围盒,它会随着物体的移动、缩放、旋转。简单来说,它就是一个能够旋转的AABB包围盒。在Cocos2d-x中使用过物理引擎的开发者一定见过当我们在物理世界中创建一个物体并开启调试模式时,这个物体会被红色的矩形包围,当物体做平移或旋转时,这个红色矩形也会做同样的操作,这个红色矩形正是该物体的OBB包围盒。如图1-1所示:
在这里插入图片描述

图1-1 相对于AABB包围盒来讲,OBB在碰撞精度上要高于AABB,但是精确度的提高同时带来的就是效率的降低,OBB的算法无疑是要比AABB复杂的,同样内存消耗也会更大,这个问题我们可以从OBB的表达式来得到结论。

OBB包围盒的表达式:

表达一个AABB包围盒或OBB包围盒都有若干种方式,但是无疑需要选中里面最优的一种。对于AABB来说,通常只要使用两个顶点的坐标信息标识一个AABB包围盒就可以了,其它的顶点信息都可以通过计算得出。但是对于OBB包围盒的表达方式只有两点信息显然是不够的。
想要唯一标识一个OBB包围盒我们大概会想到,使用8个顶点的集合、6个面的集合、1个顶点和3各彼此正交的边向量,又或者是1个中心点、1个旋转矩阵和3个1/2边长(注:一个旋转矩阵包含了三个旋转轴,若是二维的OBB包围盒则是一个中心点,两个旋转轴,两个1/2边长)。
上述最后一种方法就是最常用的方法,下面来看一段Cocos2d-x 3.3beta0中CCOBB.h中的代码:

01.Vec3 _center; // 中心点

02./*

03.以下三个变量为正交单位向量,

04.定义了当前OBB包围盒的x,y,z轴

05.用于计算矢量投影

06.*/

07.Vec3 _xAxis; // 包围盒x轴方向单位矢量

08.Vec3 _yAxis; // 包围盒y轴方向单位矢量

09.Vec3 _zAxis; // 包围盒z轴方向单位矢量

10.Vec3 _extents; // 3个1/2边长,半长、半宽、半高

Cocos2d-x 3.0beta0在CCOBB.h中定义了五个成员变量,每一个数据类型都是一个三维向量,包含了3个浮点数。也就是说,表达一个OBB包围盒需要15个float类型的变量,占用60个字节,然而表示一个AABB包围盒仅需要两个顶点,24个字节,从这一点上来说,OBB的内存消耗算很高了。

一种减少开销的方案是:只存储旋转矩阵的两个轴,只是在测试时利用叉积计算第三个轴,这样可以减少CPU操作开销并节省3个浮点数分量,降低20%内存消耗。

包围盒是一个简单的几何空间,里面包含着复杂形状的物体。最常见的包围盒算法有包围球(Sphere),轴对齐包围盒(Axis-aligned bounding box)AABB盒,OBB方向包围盒(Oriented bounding box), FDH固定方向凸包(Fixed directions hulls或k-DOP)等。这些表示法对于规则形状的物体较为有效,计算速度较快,但在捕捉不规则形状时由于包含了一定的无用空间,因此可能存在一定的精度损失。

OBB紧凑地贴合物体的实际形状,与物体的主要方向对齐。这种贴合性使得OBB能够较精确地反映被包围物体的外形,它减少了不必要的安全距离。

虽然OBB的碰撞检测计算复杂度高于AABB,但它在处理复杂或长条形状物体时更为有效,因为它减少了误报的碰撞检测次数。与AABB不同,OBB随物体旋转而旋转,保持与物体的相对方向一致。这使得OBB在处理旋转物体时保持了包围盒的大小和形状不变,从而在动态环境中提供了更稳定的避障性能。

OBB盒有不同的表示方法,首选的是一个中心点加一个主方向矩阵和三个半边长度,这种表示方法更易于进行包围盒与包围盒之间的交叉测试。
在这里插入图片描述
在这里插入图片描述

第二步,计算所有顶点的平均位置即几何中心,可以初步确定为OBB盒的中心点。

中心点= 。其中,N是顶点的数量,Pi是第 i个顶点的位置。

第三步,进行PCA分析,获取这组数据的主要分布方向。

主成分分析(PCA)是一种通过正交变换,将一组可能相关的变量集合变换成一组线性不相关的变量集合,即主成分。在这里引入协方差矩阵的概念,协方差表示的使两个变量之间的线性相关程度。协方差越小则表示两个变量之间越独立,即线性相关性小。

由此可以得到一个协方差矩阵(if 三维数据)

主对角线的元素表示变量的方差,主对角线的元素较大则表示强信号。非主对角线的元素表示变量之间的协方差,较大的非对角线元素表示数据的畸变。由于协方差矩阵是一个实对称矩阵,所以为了减小畸变,可以重新定义变量间的线性组合,将协方差矩阵相似对角化。

通过矩阵相似变换可以求得其特征值和特征向量Q,特征向量代表数据中的主要方向,而对应的特征值则表示这些方向的方差大小,即分布的广度。

第四步,确定OBB包围盒的朝向和中心点。

第五步,投影计算半边长度。将各个顶点投影到主轴上,计算投影后的极值,物体的尺寸即可通过计算最大值和最小值的差来得到,由此可以得到各个主轴方向的半边长度。

由此,基本上可以生成一个OBB包围盒。

如何判断多个OBB盒是否相撞?

分离轴定理:即如果存在一个轴(即分离轴),使得将两个对象在这个轴上的投影分开,那么这两个对象不相交。而在两个OBB包围盒,至多存在15个轴。两个OBB的每个局部坐标轴(共6个轴);两个盒子的轴之间的交叉乘积(可能的9个轴)。但是绝多数情况下是不需要全算完的。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你一身傲骨怎能输

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值