降维检测物体碰撞

 

最近了解了一种用 扫描线算法检测碰撞 的流程算法

原来不是叫扫描线算法。。。数组

 

拿 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 轴上全部相交的物体。两个方向上同时相交的则表示在 游戏中发生了碰撞。spa

  算法时间复杂度理论上是 n*n,可是实际上不会有这么高,通常游戏中,物体相对稀疏,因此很容易就会跳出内层循环。排序

  当物体移动时,为了不从新作一遍投影操做,能够直接用二分查找在 xLineList 中查找,而后修改 start、end。也能够用额外的一个 map 来维护每一个 struct 在数组中的下标。由于列表基本上是有序的,因此再次排序时,时间复杂度很低。游戏

 

 

   其余诸如四叉树、八叉树,最大包围盒树,二维空间划分 BSP,格子划分法等,均可以用来作碰撞检测,可是复杂度上并无特殊的优点,实现起来复杂度却是高了很多。若是有特殊的需求却是可使用。object

相关文章
相关标签/搜索