AABB包围盒算法,在2D碰撞检测中的实现_weixin_34038293的博客-程序员秘密

技术标签: 数据结构与算法  

Author: bugall
Wechat: bugallF
Email: [email protected]
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为碰撞物体的数量)。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34038293/article/details/89287535

智能推荐

DAY3-JDBC+Tomcat实现简易登陆系统_okita_05的博客-程序员秘密

目录bean包下User类dao包下UserDao类service包下UserServiceImpl类和UserService接口servlet包下HelloServlet类和LoginServlet类util包下DBUtil类xml文件笔记bean包下User类public class User { public User() { } public User(int id, String username, String password) { this.id

OpenGL编程指南-->深度缓冲区原理以及为什么要用它_little_angel的博客-程序员秘密

深度缓冲区原理以及为什么要用它                                                                                                    ----------------参考资料《OpenGL编程指南》1.在开始介绍深度缓存之前,先了解一下隐藏表面消除。     隐藏表面消除(hidden-su

[导入]【翻译】WF从入门到精通(第一章):WF简介_weixin_30763397的博客-程序员秘密

摘要: 学习完本章,你将掌握:1.了解工作流的概念和理论2.把WF和BizTalk与WCF做比较3.开始使用WF进行编程4.知道怎样使用Visual Studio工作流支持阅读全文--------------------------.NET技术大会期待您的参加新闻:中国网民上网劲头比美国大导航:博客园首页知识库新闻招聘社区小组博问网摘找找看文章来...

java1.5连接oracle12c_解决Java连接Oracle 12c存在的问题_weixin_39716877的博客-程序员秘密

感谢作者原文链接:https://blog.csdn.net/peng_wei_kang/article/details/804034861.发现项目报以下错误:Caused by: java.sql.SQLException: ORA-28040: 没有匹配的验证协议at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:439)a...

mysql删除表中指定数据,delete from..where_weixin_34342578的博客-程序员秘密

mysql -uxx -pyyyselect count(id) from lottery.mop_bet_order_history where created_at < '2015-11-01' and created_at > '2015-10-01';delete from lottery.mop_hot_history where cre...

c++中list, vector, map, set 区别与用法比较_Sunc23的博客-程序员秘密

List封装了链表,Vector封装了数组, list和vector得最主要的区别在于vector使用连续内存存储的,他支持[]运算符,而list是以链表形式实现的,不支持[]。Vector对于随机访问的速度很快,但是对于插入尤其是在头部插入元素速度很慢,在尾部插入速度很快。List对于随机访问速度慢得多,因为可能要遍历整个链表才能做到,但是对于插入就快的多了,不需要拷贝和移动数据,只

随便推点

杜利特尔 (Doolittle)矩阵分解法求线性方程组的解_doolittle分解_油醋三椒的博客-程序员秘密

简介  若方阵 A 可以分解为一个下三角矩阵 L 和一个上三角矩阵 U的乘积,即 A = LU,则这种分解称为 A 的一种三角分解或 LU分解。如果 L 为单位下三角矩阵,则称为杜利特尔 (Doolittle)。 以四阶矩阵为例,可分解为以下形式:实例代码#include<iostream>using namespace std;int n;double a[1...

zabbix添加telnet监控_zabbix telent_机智的埃努的博客-程序员秘密

添加针对端口监听telnet的监控项应运营需求,添加程序端口的telnet监控。整体思路如下,1.收集当前ip及端口情况,形成test文件,后边会被ansible批量执行时调用2.将脚本2(monitor_listen_port.py)放到各机子下的/etc/zabbix/script/monitor_listen_port.py,并修改定时任务,这两项写到ansible-playbook中执行,...

如何检测晶振是否合格?_ay18991283724的博客-程序员秘密

本文我们主要讲述可了石英晶体振荡器的应用设备,以及对石英晶体振荡器进行检定时需要用到的设备及相关注意事项。石英晶体振荡器是利用石英晶体的压电效应制成,其通用说法就是我们平时提到的晶振,最常用的如温补晶振,恒温晶振等,不同类型的晶振,其技术指标有很大的差别。晶振广泛用于电子测量仪器,如我们经常接触到的SYN5301型时间检定仪,SYN5605型时间间隔测量仪,SYN5602型电子停车计时收费装置...

ByteTrack翻译与解读_WZZZ0725的博客-程序员秘密

这里写目录标题AbstactIntroduction论文地址:https://arxiv.org/abs/2110.06864代码地址:github.com/ifzhang/ByteTrackAbstact多目标跟踪 (MOT) 旨在视频中预测目标的bounding boxes和identities。大多数的方法通过关联一些得分高于阈值的检测框来得出identities,那些得分比较低的目标(比如被遮挡的物体),就被简单的过滤掉了,这样的话会造成一些真正的目标的丢失以及错误的预测轨迹。为了解决这个问

Android Activity界面切换动画_android activity.enter动画_小不懂0706的博客-程序员秘密

最近做项目,发现Activity界面切换跳转时,切换动画不一致,有的左进右退,有的右进左退,有的左进左退,有的右进右退,视觉交互效果不是很好,通过查资料,采用以下方法可以解决。主要是通过AppTheme,直接在主题中修改activity动画样式,具体如下:1.定义包含动画的Activity主题<!-- Base application theme. --> &lt...

推荐文章

热门文章

相关标签