两个圆相离当且仅当圆心距离严格大于半径之和;实际编码中应使用平方距离与(r1+r2)²比较,先校验半径是否有限,且必须用>而非>=以确保严格无交点。

判断两个圆是否相离的数学逻辑
两个圆相离,当且仅当它们的圆心距离严格大于半径之和。这是欧氏几何中的基本结论,不依赖坐标系方向或象限,只和 sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)) 与 r1 + r2 的大小关系有关。
实际编码中,为避免浮点开方运算和精度误差,推荐用平方距离比较:直接计算 (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2),再与 (r1 + r2) * (r1 + r2) 比较。
C++实现时必须处理的边界情况
半径为负数、NaN 或无穷大时,std::sqrt 或比较可能产生未定义行为。生产代码里不能假设输入合法。
- 先用
std::isfinite(r1)和std::isfinite(r2)检查半径是否有效 - 显式拒绝
r1 或 <code>r2 —— 数学上半径非负,负值应视为错误输入 - 若任一圆心坐标是
NaN,整个距离计算结果为NaN,任何比较都返回false,需提前用std::isnan()拦截
一个安全、零依赖的判断函数示例
不需要引入 <cmath></cmath> 里的 sqrt,也不依赖 Boost 或 Eigen:
bool circles_separated(double x1, double y1, double r1,
double x2, double y2, double r2) {
if (!std::isfinite(x1) || !std::isfinite(y1) ||
!std::isfinite(x2) || !std::isfinite(y2) ||
!std::isfinite(r1) || !std::isfinite(r2)) {
return false; // 输入非法,无法判定相离
}
if (r1 double dx = x1 - x2;
double dy = y1 - y2;
double dist_sq = dx * dx + dy * dy;
double sum_r = r1 + r2;
return dist_sq > sum_r * sum_r;
}
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
注意:这里用 > 而非 >=,因为“相离”严格指无交点(含外切都不算相离);若需求是“不相交”(含外切),则改为 >=。
性能与精度取舍的现实提醒
在嵌入式或高频调用场景(如物理引擎每帧检测上千对圆),平方比较确实更快,但要注意:double 的乘法可能溢出(例如极大坐标值),而 float 下更易发生。如果坐标范围不可控,应先做粗略范围检查,或改用 std::hypot(它内部做了防溢出处理,但慢一些)。
另外,IEEE 754 下 0.1 + 0.2 != 0.3 这类问题在半径或坐标含小数时依然存在,但相离判断本身对微小误差不敏感——只要误差没大到让 dist_sq 错跨 (r1+r2)² 边界,结果就可靠。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










