AABB碰撞判定只需检查x、y方向是否均重叠;用min_x/max_x/min_y/max_y定义更安全,避免坐标系歧义。

用分离轴定理快速判断AABB碰撞
两个AABB不碰撞,当且仅当在x轴或y轴(2D)上完全分离。这是最直接、最高效的做法,不需要开方、三角函数或向量运算。
核心逻辑就是检查:是否「x方向重叠」且「y方向重叠」。只要有一个方向不重叠,就无碰撞。
-
rect1.left rect2.left表示x方向重叠 -
rect1.top rect2.top表示y方向重叠(注意:假设y轴向下为正,如多数图形API) - 若使用y轴向上坐标系(如OpenGL默认),则把
top和bottom的大小关系反过来,或统一用min_y/max_y字段避免歧义
用min/max字段定义AABB更安全
用left/right/top/bottom容易在坐标系切换时出错;推荐用min_x、max_x、min_y、max_y——语义清晰,适配任意y方向约定。
碰撞判定代码可写成:
立即学习“C++免费学习笔记(深入)”;
bool intersect(const AABB& a, const AABB& b) {
return a.min_x < b.max_x && b.min_x < a.max_x &&
a.min_y < b.max_y && b.min_y < a.max_y;
}- 注意是
不是<code>:若只接触边线(如<code>a.max_x == b.min_x),按常规物理引擎定义视为「未碰撞」 - 如果业务需要包含边线接触(例如UI点击热区),改用
并确保所有AABB字段定义一致 - 该函数对浮点数也适用,但要注意精度问题:比较前可加极小容差(如
1e-6f),尤其当坐标来自计算而非手动赋值时
常见错误:误用中心+宽高做条件判断
有人会写abs(center1.x - center2.x) 这类形式,逻辑没错,但隐患多:
- 需额外计算中心点和半宽/半高,增加CPU开销(虽小但累积)
- 若矩形缩放或旋转后仍沿用此方式,会误判——它只对纯AABB有效,而名字里没体现约束
- 宽高为负时(比如构造错误或镜像变换),结果不可靠;而
min_x/max_x天然保证min_x ,更容易做断言保护 - 调试时打印
min_x/max_x比看center+half_width更直观,一眼看出是否反向
性能与SIMD优化提示
单次判定开销几乎可忽略,但若每帧要检测上万对AABB(如粒子系统、Tilemap拾取),可考虑批量向量化。
- 主流编译器(GCC/Clang/MSVC)对连续内存中的
min_x数组做循环自动向量化,前提是结构体布局规整(如SOA或AoS with alignas(16)) - 手写AVX指令时,常用
_mm_cmplt_ps并行比较四组min_x与max_x,但需注意数据对齐和剩余元素处理 - 真正卡性能的往往不是判定本身,而是遍历逻辑——先用粗略空间划分(如Grid、Quadtree)减少候选对数量,再调用这个函数
边界情况永远比想象中多:空矩形(min_x >= max_x)、NaN坐标、跨极大坐标的浮点溢出——上线前至少加一条assert(!std::isnan(a.min_x))类检查。


















