圆A包含圆B当且仅当圆心距加圆B半径不超过圆A半径,即distance(A.center, B.center) + B.radius ≤ A.radius。

判断圆A是否包含圆B的数学逻辑
两个圆之间的包含关系,本质是圆心距离与半径差的比较。如果圆A要完全包含圆B(含边界),必须满足:distance(A.center, B.center) + B.radius 。注意不是简单的“圆心在A内”,因为即使B的圆心在A内部,B仍可能伸出A外——得把B整个“塞进去”。
用std::hypot算圆心距更安全
直接写 sqrt(dx*dx + dy*dy) 容易溢出或精度丢失,尤其当坐标值很大时。std::hypot(dx, dy) 内部做了缩放处理,数值更稳。
实操建议:
- 始终用
std::hypot计算二维欧氏距离,别手写sqrt - 比较时用
而非 <code>,否则相切情况会被漏判(题目要求“包含”,含边界) - 若坐标类型为
float,建议用std::hypotf;double用std::hypot
示例:
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
struct Circle { double x, y, r; };
bool contains(const Circle& a, const Circle& b) {
double dx = a.x - b.x;
double dy = a.y - b.y;
return std::hypot(dx, dy) + b.r <= a.r;
}
中心点单独判断的常见误用场景
有人会先检查 b 的圆心是否在 a 内(即 std::hypot(dx, dy) ),再加其他条件。这容易出错:它只保证圆心被包住,不保证整个圆B被包住。比如 <code>a.r == 5,b.r == 4,圆心距为 1.1 —— 圆心在a内,但 1.1 + 4 > 5,B明显超出A边界。
所以不要拆成两步验证。直接用 distance + b.r 这一式子,一步到位。
浮点误差带来的边界问题
当两个圆恰好相切(即 distance + b.r == a.r)时,浮点计算可能因舍入导致结果略大或略小。实际项目中建议引入小量容差:
- 容差值通常取
1e-9(double)或1e-5(float) - 改用
std::hypot(dx, dy) + b.r - 避免用
==判断相等,所有几何比较都应带容差
真正难的不是公式本身,而是想当然地认为“中心在内就等于整体在内”,或者忽略浮点下 == 的不可靠性。

















