圆心为(cx, cy), 半径为r的圆:
两圆方程组联立后,求方程组的解
几种情况
1) 没有交点
2) 一个交点
3) 两个交点
public static bool IsCircleIntersect2(Vector2 c1, float r1, Vector2 c2, float r2, out Vector2 p1, out Vector2 p2) { p1 = Vector2.zero; p2 = Vector2.zero; float rSum = r1 + r2; float sqrRSum = rSum * rSum; float sqrDistCenter = (c1 - c2).sqrMagnitude; if (sqrDistCenter > sqrRSum) //圆不相交 return false; if (Mathf.Approximately(sqrDistCenter, sqrRSum)) //一个交点 { p1 = c1 + (c2 - c1) * r1 / rSum; p2 = p1; return true; } float rSub = r1 - r2; float sqrRSub = rSub * rSub; if (sqrDistCenter < sqrRSub) //在圆内 return false; if (Mathf.Approximately(sqrDistCenter, sqrRSum)) //一个交点 { p1 = c1 + (c2 - c1) * r1 / rSub; p2 = p1; return true; } float sqrR1 = r1 * r1; float sqrR2 = r2 * r2; //(x-a)^2+(x-b)^2=r^2 //两圆交点连成的直线点斜式: y=kx+t float k = (c2.x - c1.x) / (c1.y - c2.y); float t = (c1.x * c1.x - c2.x * c2.x + c1.y * c1.y - c2.y * c2.y + sqrR2 - sqrR1) / (2 * (c1.y - c2.y)); //Debug.Log($"y={k}x+{t}"); //代入圆1的方程, 化解后得到关于x的一元二次方程标准式:ax^2+bx+c=0 float a = (1 + k * k); float b = (2 * k * t - 2 * c1.x - 2 * k * c1.y); float c = t * t - 2 * t * c1.y - sqrR1 + c1.x * c1.x + c1.y * c1.y; //Debug.Log($"{a}x^2+{b}y+{c}=0"); //求根公式求出x=-b+sqrt(b^2-4ac)/(2a) float x1 = (-b + Mathf.Sqrt(b * b - 4 * a * c)) / (2 * a); p1 = new Vector2(x1, k * x1 + t); float x2 = (-b - Mathf.Sqrt(b * b - 4 * a * c)) / (2 * a); p2 = new Vector2(x2, k * x2 + t); return true; }
参考
求两个圆交点的坐标-解析表达式推导及编程_两个圆的交点坐标公式-CSDN博客
怎样求解一元二次方程(四种)-百度经验 (baidu.com)
求两圆相交的交点的方法 - 简书 (jianshu.com)