AABB矩形不相交当且仅当x或y轴上投影完全分离;因无旋转,只需比较min/max坐标区间是否重叠,无需用中心点与半宽计算。

两个 AABB 矩形不相交,当且仅当在任意一个轴(x 或 y)上它们的投影完全分离。这是所有判断逻辑的根基,不是经验法则,而是数学定义——AABB 本身没有旋转,所以只需分别检查横纵坐标区间是否重叠。
用 min/max 坐标直接比较,别算中心和半宽
很多人习惯把 AABB 表示为中心点 center 和半宽 halfExtents,再写 abs(center1.x - center2.x) 。这没问题,但容易引入浮点误差累积、符号处理错误,且可读性差。更稳妥的是直接用左/右/下/上边界:
- 设矩形 A 的 x 范围是
[ax_min, ax_max],y 是[ay_min, ay_max] - 矩形 B 同理为
[bx_min, bx_max]和[by_min, by_max] - 不相交条件:
ax_max - 相交即取反:
!(ax_max
注意坐标系方向和“min/max”命名一致性
很多 bug 来自假设 y 向上为正,但实际渲染或物理引擎中 y 向下为正(比如 SDL、SFML 默认窗口坐标)。此时 y_min 可能比 y_max 大——这不是数据错,是语义错。务必确认:
- 你的
_min和_max是按数值大小定义,还是按空间位置(如 “top”、“bottom”)定义 - 如果用
top/bottom,注意top 在 y 向下坐标系中成立,此时不能直接套用y_max 判定逻辑 - 统一用
left/right/bottom/top命名时,推荐先转成数值区间:y_min = std::min(bottom, top); y_max = std::max(bottom, top);
整数坐标下慎用 和 >= 边界判定
>= 边界判定当 AABB 用整数表示(如像素坐标、网格索引),是否允许“边接触即碰撞”需明确。例如两个矩形紧贴右左边界:ax_max == bx_min。此时:
- 若要求“只要像素/格子有公共边就算碰撞”,应使用
ax_max 作为分离条件之一,然后取反 - 但更常见的是“仅内部重叠才算”,即严格大于/小于才分离,所以保留
ax_max - C++ 中
std::numeric_limits等极端值下,用::max() ax_max 不会溢出;而用中心+半宽方式可能在加法时溢出
最易被忽略的一点:AABB 的坐标必须来自同一空间——不要拿世界坐标矩形和屏幕坐标矩形直接比,也不要在未做逆变换前,把带缩放的 UI 矩形和逻辑矩形混用。碰撞前先确认坐标系对齐,比优化判定逻辑重要十倍。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











