不相交当且仅当rect1右边界≤rect2左边界、或rect1左边界≥rect2右边界、或rect1下边界≤rect2上边界、或rect1上边界≥rect2下边界;否则相交。

用分离轴定理快速判断矩形相交
两个轴对齐矩形(AABB)是否相交,最常用也最高效的方法是「反向思维」:先判断是否**不相交**,再取反。只要任一方向上两个矩形完全分离,就一定不相交;否则相交。
假设矩形用左上角 x、y 和宽 w、高 h 表示(y 向下为正),则不相交的条件是:
rect1.x + rect1.w (rect1 在 rect2 左侧)rect2.x + rect2.w (rect2 在 rect1 左侧)rect1.y + rect1.h (rect1 在 rect2 上方)rect2.y + rect2.h (rect2 在 rect1 上方)
只要满足其中任意一个,就返回 false;否则返回 true。这个逻辑比逐边检测或求交集更轻量,且无浮点误差风险(整数坐标下完全精确)。
注意坐标系和矩形定义方式差异
C++ 里没有统一的矩形类型,不同场景下 Rect 的字段含义可能完全不同,直接套用公式会出错。
常见情况包括:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- OpenCV 的
cv::Rect:成员是x、y、width、height,左上为原点,y 向下 —— 可直接用上述逻辑 - Qt 的
QRect:默认也是左上原点,但若启用了QRect::normalize()或使用了topLeft()/bottomRight(),需确认x≤right()且y≤bottom() - 自定义结构体:务必检查是否存储的是
left/right/top/bottom,如果是,相交判断应写成:!(r1.right()
处理浮点坐标时的边界问题
当矩形用 float 或 double 表示(如 OpenGL UI、游戏物理),严格等于(==)不可靠,但「是否相交」本身是几何问题,关键在**是否重叠**,而非是否恰好贴边。
此时仍可用分离轴逻辑,但比较需容忍极小误差:
- 把
换成 <code>(如 <code>1e-6f)不必要,反而易引入误判 - 正确做法是保持原逻辑不变 —— 浮点矩形「刚好接触」(如
r1.right == r2.left)在数学上属于不相交,多数业务也如此定义;若需「接触即相交」,改用替换 <code> 即可 - 真正要防的是计算过程中的精度丢失,比如由变换矩阵生成的顶点坐标,建议在做相交前先用
std::round或区间量化预处理(视精度要求而定)
旋转矩形?不能直接用 AABB 判断
如果矩形绕中心或某点旋转过,它不再是轴对齐的,上述所有基于 x/y/w/h 的判断都会失效 —— 因为它的投影在 x/y 轴上已变宽/变高,仅靠包围盒会漏判或误判。
此时必须升级方法:
- 用分离轴定理(SAT):对两个凸多边形(四边形),检查所有边的法向量方向上的投影是否分离。共需最多 8 次投影比较
- 借助图形库:如 Clipper2 的
IsPolygonContains或 Boost.Geometry 的boost::geometry::intersects(),传入四个顶点构成的多边形 - 简单近似:先用旋转后顶点算出 tight AABB,再做 AABB 相交;快但保守(可能返回 true 实际不交)
别试图用 sin/cos 手动展开四个顶点再求交——容易写错且无必要,除非你明确需要极致性能且只处理单种旋转角。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










