aabb碰撞检测的数学本质是判断两个轴对齐矩形在x轴和y轴上是否同时重叠,仅需四次比较,无需旋转或复杂运算;标准实现推荐统一使用min/max坐标形式,并用

什么是AABB碰撞检测的数学本质
AABB(Axis-Aligned Bounding Box)碰撞检测,本质就是判断两个矩形在x轴和y轴上是否**同时重叠**。只要有一个轴不重叠,就无碰撞;必须x方向重叠 且 y方向重叠,才算发生碰撞。
关键点在于:不需旋转、不需计算交点、不涉及向量叉乘——只做四次比较。这也是它快且被广泛用于前置粗筛的原因。
标准实现:用min/max坐标还是left/top/width/height?
两种常见坐标表示法,写法不同但逻辑一致。选哪种取决于你手头的数据结构:
- 若矩形用
left、top、width、height表示(如SDL或某些GUI库),则右边界是left + width,下边界是top + height - 若用
min_x、min_y、max_x、max_y(更贴近AABB本意),直接比较即可
推荐统一转为 min/max 形式,避免每次重复加减。例如:
bool collide(const Rect& a, const Rect& b) {
return !(a.max_x
<p>注意:用 <code> 而非 <code>,否则边刚好贴合时会误判为不碰撞(取决于业务需求,但多数物理引擎认为“接触”即碰撞)。</code></code></p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2823" title="C++14"><img
src="https://img.php.cn/upload/manual/001/431/639/6ac8b33c327c4749.png" alt="C++14" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="overflowclass">C++14</a>
<p class="overflowclass">C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<h3>容易踩的坑:坐标系方向与浮点精度</h3>
<p>常见错误不是逻辑错,而是数据源隐含假设被忽略:</p>
- Y轴朝下(如屏幕坐标系)时,
top 仍成立,但如果你误把 <code>top当作最大y值,就会翻转判断条件 - 使用
float或double坐标时,避免直接用==或判断边界相等;若需鲁棒性,可加极小epsilon容差,但AABB通常不需要——除非你在做连续碰撞检测(CCD) - Rect结构体未保证
min_x ,传入无效矩形(如width为负)会导致结果不可靠;建议在构造函数中归一化
性能提示:内联与分支预测
这个函数足够简单,应声明为 inline(尤其在循环中高频调用时)。现代编译器通常自动内联,但显式写上更稳妥:
inline bool collide(const Rect& a, const Rect& b) { ... }
短路求值(||)让大多数情况只需2次比较就能退出——比如a在b右边,第二项就false,后续不执行。所以实际平均开销远低于4次比较。
真正复杂的地方不在算法本身,而在你怎么定义“矩形”:坐标来源是否可信、是否需要处理空矩形、是否要支持变换后的AABB(那就要先变换再检测)。这些才是落地时最常卡住的点。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










