两圆外切的条件是圆心距等于半径之和且半径非负。代码通过std::hypot计算距离,用误差容忍判断dist≈r1+r2,并前置校验r1≥0、r2≥0及dist有效。

判断两圆外切的数学条件和代码实现
外切的本质是两圆心距离恰好等于半径之和。只要算出圆心距 dist,再和 r1 + r2 比较即可,但必须考虑浮点误差。
- 用
std::hypot(dx, dy)计算圆心距,比手动开方更稳定 - 不要直接写
dist == r1 + r2,改用误差容忍:std::abs(dist - (r1 + r2)) - 推荐
eps = 1e-9,对 double 足够安全;若坐标是 int 且半径不大,也可用eps = 1e-5 - 注意半径必须为非负值,建议提前断言或过滤
r1
判断两圆内切的关键逻辑和边界情况
内切要求一圆在另一圆内部、且仅有一个公共点,数学条件是圆心距等于半径之差的绝对值:dist == std::abs(r1 - r2)。但这里陷阱更多。
- 必须先确保大圆能包住小圆:即
dist + min(r1, r2) == max(r1, r2)在浮点下等价于std::abs(dist - std::abs(r1 - r2)) - 当
r1 == r2时,内切退化为同心圆重合——此时圆心距为 0,但不算内切(而是无限多交点),需额外排除:if (r1 == r2) return dist - 如果
dist为 0 且r1 != r2,才是真正的内切(小圆在大圆正中心相切)
把内切和外切合并成一个函数的实用写法
实际项目中通常需要统一判断“是否相切(含内外)”,可封装为返回枚举或 bool + 类型标识。
- 先计算
dist = std::hypot(x1-x2, y1-y2) - 检查外切:
std::abs(dist - (r1 + r2)) - 检查内切:
r1 != r2 && std::abs(dist - std::abs(r1 - r2)) (隐含了 <code>dist >= 0) - 注意:若
dist为 NaN(比如输入 NaN 坐标),所有比较都为 false,建议前置校验
bool isTangent(double x1, double y1, double r1,
double x2, double y2, double r2) {
const double eps = 1e-9;
double dx = x1 - x2, dy = y1 - y2;
double dist = std::hypot(dx, dy);
if (r1 <h3>容易被忽略的坐标系与精度问题</h3><p>看似简单的几何判断,在真实代码里常因坐标来源不同而翻车。</p>
- 如果圆心来自像素坐标(int),但半径是 float 运算结果,混用类型可能导致隐式转换误差,建议统一为
double - WebGL 或 OpenGL 中 Y 轴朝下,不影响距离计算,但若从图像坐标转世界坐标没翻转,会导致
dy符号错——不过std::hypot对符号不敏感,所以仍正确 - 极端情况:一圆半径为 0(点圆),此时“内切”变成点在另一圆上,“外切”变成点在圆外且距离等于半径——上述公式依然成立,无需特殊处理
真正要小心的是 eps 的尺度:用 1e-2 判断厘米级物理仿真就太大,用 1e-12 在大坐标(如 x=1e8)下可能失效——eps 应和输入量纲匹配。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











