直接结论:用圆心到AABB最近点距离的平方与半径平方比较,无需开方和分情况。先计算x、y方向到边界的最近距离dx、dy,再判断dx²+dy²≤r²是否成立。

怎么快速判断圆和AABB是否相交
直接结论:不用开方,不用分八种情况手动判断,用「圆心到矩形的最近点距离平方」和「半径平方」比较。这是最稳定、最高效的做法。
核心思路:把问题降维成“点到矩形距离”
轴对齐矩形(AABB)没有旋转,所以圆心 center 到它的最近距离可以逐轴计算——x方向取到左右边界的最近距离,y方向取到上下边界的最近距离,组合起来就是矩形内(或边上)离圆心最近的点坐标。
这个最近点可能在矩形内部、边上或角上,但无需分类讨论,统一用 std::clamp 或三元运算就能算出:
float dx = std::max(0.0f, std::max(center.x - rect.right, rect.left - center.x)); float dy = std::max(0.0f, std::max(center.y - rect.top, rect.bottom - center.y)); bool collision = dx * dx + dy * dy <= radius * radius;
注意:rect.left/rect.right 是x范围,rect.bottom/rect.top 是y范围(假设y向上为正);若y向下为正(如屏幕坐标),则把 top 和 bottom 含义对调即可。
立即学习“C++免费学习笔记(深入)”;
常见错误:过早开方或误用中心距
有人会先算圆心到矩形中心的欧氏距离,再减去半宽半高——这错在几何上不成立,因为矩形不是圆形,不能简单“减去半径等效量”。还有人对每个顶点都算距离再取最小,做了4次开方,性能差且结果未必对(最近点根本不在顶点上)。
- 别用
sqrt:比较平方距离完全等价,避免浮点误差和开方开销 - 别假设矩形中心参与计算:AABB碰撞本质是投影距离,中心只是中间变量,不必要
- 注意坐标系:如果矩形用
min/max表示(如rect.min.x,rect.max.x),代码要改成std::max(0.0f, center.x - rect.max.x)和std::max(0.0f, rect.min.x - center.x)
边界情况:相切算碰撞吗?
数学上相切是接触,工程中通常视为碰撞。代码里用 <= 就包含相切;若需严格“重叠”才触发,改用 <。但要注意浮点精度:当 dx*dx + dy*dy 和 radius*radius 非常接近时,可能因舍入导致误判。如有高精度要求,建议用 std::abs(dx*dx + dy*dy - radius*radius) < epsilon 加容差,但绝大多数游戏或UI场景不需要。
真正容易被忽略的是矩形为空(left >= right 或 bottom >= top)的情况——此时逻辑失效,务必在调用前确保矩形有效。


















