AABB包围盒算法,在2D碰撞检测中的实现

Author: bugall
Wechat: bugallF
Email: 769088641@qq.com
Github: https://github.com/bugall

一:介绍

碰撞检测是游戏开发中常用到的基础功能,通常的物理引擎中都会包含碰撞引擎.我们今天主要介绍
的就是Dynamic AABB Tree的实现原理,AABB Tree是个二叉树,从名字上看,像是个动态平衡树的变种。
确实在构造AABB树的时候是需要balance逻辑的。但是AABB的平衡不是基于数的深度的而是"面积",后面
会详细介绍。

为了方便介绍,后文里的将用ABT来代表AABB Tree

二:引言

图片描述

这个游戏想必大家都玩过,这里面就牵扯到一个碰撞检测的问题,需要实时检测用户控制的小车是否

碰到了障碍物,最简单的方法就是枚举每一个障碍物,判断障碍物是否跟用户控制的小车有交集。

当障碍物少的时候,比如障碍物有100~10000个的时候枚举是可以解决的,但是在一些加有物理引

擎的场景里,枚举就显然行不通了,因为需要判断每一个物体是否被其它n-1个物体碰撞。如果我们还是用

枚举的形式来做碰撞检测那么时间复杂度就是n!,如果有100个物体,那么做一次检测的时间复杂度就已经

难以接受。

在枚举算法做碰撞检测的时候有存在一个很大的问题,那就是如果两个物体距离很远,远到它们不可能
接触,但是检测中还是会枚举这对组合。

ABT是基于二叉树实现的,这时候我们能大概感觉到,它的时间复杂度将会从枚举的n*n变成nlog(n)
接下来我们看下具体原理

三:碰撞体的预处理

为什么预处理?我们看下面的两个图。如果我们需要对这两张图片做碰撞检测,该如何处理?

object.png图片描述

我们可以基于像素的对比,判断青蛙的像素坐标有没有出现在钥匙的像素坐标里,如果有重叠的部分
那说明,两个物体碰撞里,但是仔细想一下这并不是很好的办法,假如我们两个照片都是600*600像素,那么
单单这两个物体的碰撞检测的时间复杂度就是600^4。

很显然不能这么做,我么接下来对图片进行"描边"。我们就会得到两个矩形。那么接下来就好处理了。

二:ABT树的构建过程

图片描述

假设上图中的A,B,C是我们要做碰撞检测的物体,外面的蓝色框体就是我们对物体描边以后获得的矩形
接下来就是构建树的过程,上面说过ABT树中的每一个节点是AABB Tree结构。我们从左至右建树,就像构建
二叉排序树一样。

step-1: 把A加入到树结构中,作为根节点
step-2: 把B加入到数结构中,这时需要和根节点做比较,判断根节点的区域是否跟B有交集,如果有的话
        就判断子节点是否跟B有交集,如果都没有就判断B分别加入子节点区域后的面积,找到面节差最
        小的,组合。如果B与根节点没有交集,就把A和B当作一个整体重新构建轮廓(橘黄色的矩形),并
        生成A,B的父节点(上图中橘黄色的圆圈),
step-3: 把C加入到树中,判断是否有交集,方法与step-2中一样,最终得到上图中的树

最终所有的物体将会在树的叶节点上。
树中除叶节点外,所有的节点存的都是自己的面积,或是说是自己的轮廓矩形的四个点的坐标。这样的话,一旦

判断一个对象是否与树中物体碰撞,我们只需判断是否与物体所在区域有交集,如果有就说明"有可能"会碰撞,然后
接着递归向下,直到找到与目标物体碰撞的叶节点。

整个过程中,很想是一个二叉排序树,给一个数字,判断这个数字在不在二叉排序树中。
无论是二叉排序树也好还是ABT算法也好,最重要的还是它们都巧妙的使用里二分法,不要ABT算法的二分法是将
面积进行二分,尽可能的避免搜索错误区域。

所以ABT算法在检测一个物体是否与其它物体碰撞的时候时间负责度是log(n)的(n为碰撞物体的数量)。


bugall的专栏
日常工作笔记

我是一只小程序猿

889 声望
12 粉丝
0 条评论
推荐阅读
Sinon 入门,看这篇文章就够了
当我们在开发前端项目的时候, 很多时候需要根据后端返回的数据来渲染页面, 我们通常使用AJAX发送请求给服务端。当我们开发后端逻辑的时候有时候需要连接数据库,根据从数据库中得到的数据来执行后续的逻辑代码, 或...

李腾飞23阅读 24.5k

杨辉三角的5个特性,一个比一个牛皮!
杨辉三角按照杨辉于1261年所编写的《详解九章算法》一书,里面有一张图片,介绍此种算法来自于另外一个数学家贾宪所编写的《释锁算书》一书,但这本书早已失传无从考证。但可以肯定的是这一图形的发现我国不迟于1...

小傅哥3阅读 1.3k

不会数学的程序员,只能走到初级开发工程师!
在我还是初级程序员时,每天也都粘贴着代码和包装着接口。那个阶段并没有意识到数学能在编程中起到什么作用,就算学了数学的部分知识,也没法用到编程中。但后来随着编程越来越久,逐步接手核心代码块开发时候,...

小傅哥3阅读 527

封面图
stackoverflow 提问:“计算两个整数的最小公倍数的最有效方法是什么?”
作者:小傅哥博客:[链接]源码:[链接]沉淀、分享、成长,让自己和他人都能有所收获!😄一、前言嘿,小傅哥怎么突然讲到最大公约数了?这么想你肯定是没有好好阅读前面章节中小傅哥讲到的RSA算法,对于与欧拉结果...

小傅哥3阅读 1.3k

封面图
视频清晰度优化指南
随着移动互联网的深入发展,视频消费场景逐渐变成主流,早期由于手机硬件的限制问题,导致生产出来的视频画质、清晰度存在较大的问题,用户体验不太好,当时的网络也处于4G的发展阶段,网络的限制也无法持续支持...

得物技术2阅读 857

为什么不能用斐波那契散列,做数据库路由算法?
斐波那契数列出现在印度数学中,与梵文韵律有关。在梵语诗歌传统中,人们对列举所有持续时间为 2 单位的长 (L) 音节与 1 单位持续时间的短 (S) 音节并列的模式很感兴趣。用给定的总持续时间计算连续 L 和 S 的不...

小傅哥1阅读 737

封面图
“3D 元宇宙技术”在汽车新零售领域的应用与实践
随着不久前汽车之家新零售项目震撼发布,我们直击用户看车选车痛点首次提出 ABC 新体验模式,以元宇宙科技打造沉浸式交互服务,开放元宇宙能源空间站体验店,为用户打造更“有用”的体验。

之家技术阅读 5.1k

封面图

我是一只小程序猿

889 声望
12 粉丝
宣传栏