两圆相交当且仅当 |r1−r2| r1+r2 或 d
判断两圆是否相交及交点个数
两圆交点是否存在,取决于圆心距
d与两半径r1、r2的关系。直接计算前必须先分类:
— 若d > r1 + r2:外离,无交点;
— 若d :内含(或内离),无交点;
— 若d == 0 && r1 == r2:同心圆重合,无穷多交点(通常视为退化情况,按题意忽略);
— 其余情况:有 0、1 或 2 个交点。特别地,d == r1 + r2或d == abs(r1 - r2)时为相切,仅 1 个交点。用向量投影法解交点坐标(推荐)
设圆 A 圆心为
p1 = (x1, y1),半径r1;圆 B 圆心为p2 = (x2, y2),半径r2。核心思路是:先求出两圆心连线上的垂足位置(即公共弦中点),再沿垂直方向偏移得到两个交点。
关键中间量:
—d = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))(圆心距);
—a = (r1*r1 - r2*r2 + d*d) / (2*d)(从p1到垂足的投影长度);
—h = sqrt(r1*r1 - a*a)(垂足到交点的垂直距离)。
然后构造单位方向向量:
— 沿p1→p2方向单位向量:ex = ((x2-x1)/d, (y2-y1)/d);
— 垂直单位向量:ey = (-ey.y, ey.x)或直接用(-(y2-y1)/d, (x2-x1)/d)。两个交点为:
sol1 = p1 + a*ex + h*eysol2 = p1 + a*ex - h*ey注意浮点误差与退化情形处理
实际编码中,
h可能因浮点误差变成极小负数(如-1e-15),直接开方会得到NaN。务必做容错判断:
— 计算h_sq = r1*r1 - a*a后,先检查h_sq → 视为无交点;
— 若h_sq 但大于-1e-10,设h = 0(即相切);
—d接近 0 时(同心),要单独判断避免除零;
— 所有比较都应使用带 epsilon 的近似判断,而非==。立即学习“C++免费学习笔记(深入)”;