aabb重叠当且仅当在x轴和y轴上均重叠;常见错误是遗漏某轴判断或不等号方向错误。

用分离轴定理判断AABB重叠最直接
两个AABB不重叠,当且仅当它们在x轴或y轴(2D)/z轴(3D)上完全分离。反过来,只要在所有轴上都**有重叠**,就说明矩形相交。这是最可靠、最高效的判断逻辑,无需计算交点或面积。
常见错误是写成 if (left1 left2) 却漏掉y轴判断,结果在垂直方向错判为相交;或者把不等号方向搞反,比如用 替代 <code> 导致边界接触被误认为不重叠(取决于需求,但多数物理引擎把“边对边”视为碰撞)。
- 2D场景下必须同时检查x和y:两者都满足重叠条件才算相交
- 坐标系无关——无论原点在左上还是左下,只要每个AABB用
min/max统一表达,逻辑不变 - 避免使用中心+半宽高结构做比较,容易引入浮点误差或符号混淆
标准AABB结构与判断函数怎么写
推荐用两个vec2(或float[2])分别存min和max坐标。这样接口清晰,也方便扩展到3D。
典型实现如下(C++17,无依赖):
struct AABB {
float min_x, min_y;
float max_x, max_y;
};
<p>bool intersects(const AABB& a, const AABB& b) {
return !(a.max_x </p><p>注意:这里用<code>!</code>包裹四个分离条件,比写四组<code>&&</code>更易读且不易漏项。如果需要包含边界接触(如像素对齐渲染),把<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>有人会想:“算两个中心距离,再减半宽半高”——这在AABB上可行但绕远,且引入多余开方和加减运算;更危险的是,它隐含假设了坐标对齐,一旦将来支持旋转矩形(OBB),整个逻辑就失效。</p><p>还有人用<code>abs(center1.x - center2.x) ,看似简洁,但:</code></p>
- 浮点下
half_width可能因四舍五入失真,而min/max是原始输入,更可信 - 无法自然处理空矩形(
min_x > max_x)——用分离轴逻辑时,这种输入会自动返回false,符合直觉 - 多线程中若AABB被并发修改,
min/max成对读取比多次读中心+半宽更原子
实际项目里容易被忽略的边界情况
游戏或GUI系统中,AABB常来自UI布局计算、精灵包围盒或物理模拟输出,这些地方容易产出非规范数据:
-
min_x == max_x或min_y == max_y:退化为线或点,按上述函数会返回false(合理),但若业务要求“点在线段上也算碰撞”,得单独处理 - 坐标溢出:极端缩放或超大地图下,
float精度不足导致min/max顺序翻转,建议在构造AABB时加断言assert(min_x - 跨帧移动过快导致“隧道效应”:单帧检测不到碰撞,需配合连续碰撞检测(CCD)或子步进,但那是另一个层级的问题了
真正难的不是写对这个函数,而是确保传进来的min/max始终代表同一时刻、同一坐标系下的有效范围。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










