• 降维检测物体碰撞


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

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

    拿 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,格子划分法等,都可以用来做碰撞检测,但是复杂度上并没有特殊的优势,实现起来复杂度倒是高了不少。如果有特殊的需求倒是可以使用。

  • 相关阅读:
    Python六大开源框架对比:Web2py略胜一筹
    软件设计之UML—UML的构成[上]
    Web程序员最常用的11款PHP框架
    PHP常见框架
    WinCE的开发流程
    Windows10如何卸载OneDrive
    Windows系统中环境变量不展开的问题
    线程局部存储空间
    ping pathping tcping psping tracert
    ubuntu ufw 配置
  • 原文地址:https://www.cnblogs.com/cg-wang/p/6188950.html
Copyright © 2020-2023  润新知