两圆完全分离当且仅当圆心距的平方严格大于半径和的平方;需校验负半径、nan及无穷大等异常输入,避免浮点误差与误判。

判断两圆是否完全分离:核心是距离与半径关系
两个圆在二维平面中完全分离,当且仅当它们的圆心距离严格大于两圆半径之和。这是几何本质,不是近似或启发式——只要 distance > r1 + r2,就一定无交点、无接触、无包含,彼此彻底分离。
注意“完全分离”排除了所有接触情形:相切(外切或内切)、相交、内含都不算。所以必须用严格大于(>),不能用 >=。
C++ 实现时别直接开方:用平方距离避免精度与性能问题
计算欧氏距离要调用 sqrt,但比较是否分离只需判断 distance > r1 + r2。两边平方后等价于:dx*dx + dy*dy > (r1 + r2)*(r1 + r2)。这样既免去浮点开方误差,又更快。
常见错误是先算 sqrt(dx*dx + dy*dy) 再比较,尤其在循环中高频调用时,会拖慢性能且引入不必要的舍入误差。
- 输入坐标和半径应为
double或float,但比较时统一用平方形式 - 若半径可能为负,需提前校验(
r1 )并按需处理(如抛异常或取绝对值) - 当两圆之一半径为 0(退化为点),公式依然成立:点在另一圆外即算分离
边界情况必须显式检查:零半径、NaN、无穷大
真实代码里,输入未必干净。如果传入 NaN 或 INF,dx*dx + dy*dy 可能仍是 NaN,而任何与 NaN 的比较(包括 >)都返回 false,导致误判为“不分离”。这很隐蔽。
- 建议前置检查:
if (std::isnan(r1) || std::isnan(r2) || std::isnan(x1) || ...) - 对
std::isinf也要响应:若任一圆心为无穷,距离为无穷,此时除非另一圆半径也为无穷,否则必分离;但通常应视为非法输入 - 零半径合法,无需特殊分支,平方比较自然兼容
完整可嵌入函数示例
bool circles_separated(double x1, double y1, double r1,
double x2, double y2, double r2) {
if (r1 r_sum * r_sum;
}
这个函数不依赖任何第三方库,只用标准 <cmath></cmath> 中的 std::isnan(C++11 起)。如果目标平台不支持 C++11,可用 dx != dx 检查 NaN,但需确保优化器不剔除该表达式。
最易被忽略的是:很多人写完逻辑就提交,却没意识到浮点输入的脏数据会让整个判断失效——宁可多几行防御性检查,也不要靠测试“恰好没撞上 NaN”。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











