降维检测物体碰撞
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了降维检测物体碰撞相关的知识,希望对你有一定的参考价值。
最近了解了一种用 扫描线算法检测碰撞 的流程
原来不是叫扫描线算法。。。
拿 2D 游戏,游戏中的物体都是 AABB 盒来说(3D 游戏也是可以用这种方式的。2D 游戏分成 x、y 两个维度,3D 分成 x、y、z 三个维度)
1 首先以 x 轴 方向列一条直线 line,将所有的物体都投影到该直线上,于是每个物体在 line 上都映射成一条线段,有 起点 start、终点 end。
2 将这些数据存成一个结构体 struct,包含下面字段:
startPos、endPos、objectId
3 将所有数据存放到一个数组 xLineList 中,然后根据 startPos 从小到大进行快排
4 用如下方式遍历数组:
totalCount = xLineList.length
for i=0; i<totalCount; ++i
for j=i; j<totalCount; ++j
if objectI.endPos <= objectJ.startPos
//i 和 j 在 x 轴方向上有碰撞
else
break;
用上述方法拿到了 x 轴上所有相交的物体,在记录碰撞对的时候,静态物体之间的碰撞是可以忽略的,只有 dynamic 和 dynamic 或者 dynamic 和 static 之间的碰撞才有记录的必要,能省就省。用类似的方式拿到 y 轴上所有相交的物体。两个方向上同时相交的则表示在 游戏中发生了碰撞。
算法时间复杂度理论上是 n*n,但是实际上不会有这么高,一般游戏中,物体相对稀疏,所以很容易就会跳出内层循环。
当物体移动时,为了避免重新做一遍投影操作,可以直接用二分查找在 xLineList 中查找,然后修改 start、end。也可以用额外的一个 map 来维护每个 struct 在数组中的下标。因为列表基本上是有序的,所以再次排序时,时间复杂度很低。
其他诸如四叉树、八叉树,最大包围盒树,二维空间划分 BSP,格子划分法等,都可以用来做碰撞检测,但是复杂度上并没有特殊的优势,实现起来复杂度倒是高了不少。如果有特殊的需求倒是可以使用。
以上是关于降维检测物体碰撞的主要内容,如果未能解决你的问题,请参考以下文章