降維檢測物體碰撞

 

最近了解了一種用 掃描線算法檢測碰撞 的流程算法

原來不是叫掃描線算法。。。數組

 

拿 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

相關文章
相關標籤/搜索