两个轴对齐矩形重叠当且仅当在x轴和y轴上投影均重叠;即left1
用分离轴定理快速判断矩形重叠
两个轴对齐矩形(AABB)是否重叠,最可靠且高效的方法是:**检查它们在 x 轴和 y 轴上是否都存在重叠区间**。只要任一轴不重叠,整体就不重叠——这是分离轴定理在 2D 轴对齐情况下的直接应用。
别去算交点、别转角度、别调用图形库的碰撞函数。C++ 原生比较就能搞定,时间复杂度 O(1),无分支预测风险。
- 假设矩形用
left、right、top、bottom表示(y 向下为正,常见于 GUI 或 SDL),则重叠条件是:left1- 若用
x、y、width、height表示(y 向上为正,如 OpenGL 纹理坐标),先转成边界再判断:right = x + width,bottom = y - height(注意 y 方向符号)- 务必确保
left 且 <code>top ;若矩形可能被用户拖拽翻转(如框选),需先归一化:<code>std::minmax(left, right)避免浮点精度导致的误判
当矩形坐标是
float或double时,直接用==或判断边界相等会出问题——比如两个矩形“刚好贴边”,理论上不重叠,但因计算误差可能被判定为重叠或不重叠。
- 关键不是加 epsilon,而是明确业务语义:**“贴边”算不算重叠?** 大多数场景(如 UI 布局、碰撞检测)应定义为「不重叠」,所以用严格不等式
和 <code>>即可- 若需包含“接触即重叠”,改用
和 <code>>=,但必须同步保证所有矩形数据已做 round-to-nearest 或 floor/ceil 对齐(尤其来自像素坐标时)- 不要对
float边界做std::abs(a - b) 再判断相等——这会让逻辑变成三态(重叠 / 接触 / 分离),反而增加后续分支处理成本用 std::pair 或结构体封装提升可读性
裸写四个变量名(
l1,r1,t1,b1)极易传错顺序,也难维护。C++17 起推荐用命名结构体,而非std::tuple或std::pair<:pair...></:pair...>。struct Rect { float left, right, top, bottom; bool overlaps(const Rect& other) const { return left
- 成员变量顺序固定为
left/right/top/bottom,和 CSS box model 一致,降低团队理解成本- 把判断逻辑收进成员函数,避免外部重复写四组比较;若需支持不同坐标系(如 y 向上),可加模板参数或枚举标识
- 不建议用
std::array<float></float>—— 语义丢失,a[0]是什么?没人能一眼看懂注意 SDL2 / Qt / OpenCV 等库的坐标约定差异
不同库对矩形的定义方式不同,直接套用同一套判断逻辑会出错。重点不是“哪个对”,而是“你当前用的 API 返回的是什么”。
- SDL2 的
SDL_Rect是{x, y, w, h},且 y 向下为正,所以top = y,bottom = y + h;别误以为y是 top- Qt 的
QRect默认 y 向上为正,但top()返回最小 y 值(即上边界),bottom()返回最大 y 值(即下边界)——它内部已帮你归一化,可直接用intersects(),但自己实现时仍要确认其top()是否真等于y- OpenCV 的
cv::Rect是{x, y, width, height},y 向下为正,y是 top,y + height是 bottom;但注意其area()为正,说明 width/height 恒 ≥ 0最稳妥的做法:拿到矩形数据后,立刻转成你统一的
Rect结构体,再调用overlaps()。中间多一次赋值,远比后期 debug 坐标翻转问题省时间。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!












