给出两圆的圆心坐标和半径, 求出两圆交点的坐标
如下图
可根据余弦定理求出角a的大小, 再根据函数atan2()可求出向量C1C2的方位角t
这样一来, 我们所求的交点就是以圆心C1.c为起点, 大小为c1.r ,角度为 t+a 和 t-a 的两个向量
程序代码参考
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
typedef struct node
{
double x, y;
}NODE;
inline NODE Vector(NODE A, NODE B);
inline double dis2(NODE a, NODE b);
double angleA(NODE O1, double r1, NODE O2, double r2);
double angleT(NODE O1, NODE O2);
NODE polar(double a, double r);
int main()
{
NODE O1, O2;
double r1, r2;
cin >> O1.x >> O1.y >> r1;
cin >> O2.x >> O2.y >> r2;
if (sqrt(dis2(O1,O2))>r1+r2)
{
cout << "不存在交点" << endl;
return 0;
}
double t = angleT(O1, O2);
double a = angleA(O1, r1, O2, r2);
NODE polar1 = polar(t+a,r1);
NODE polar2 = polar(t-a, r1);
NODE x1 = {O1.x+polar1.x,O1.y+polar1.y};
NODE x2 = {O1.x+polar2.x,O1.y+polar2.y};
cout << x1.x << ' ' << x1.y << ' '<<x2.x<<' '<<x2.y<<endl;
return 0;
}
NODE polar(double a, double r)
{
return{ r*cos(a), r*sin(a) };
}
double angleA(NODE O1, double r1, NODE O2,double r2) //求角a
{
return acos((r1*r1+dis2(O1,O2)-r2*r2)/(2*r1*sqrt(dis2(O1,O2)))); //余弦定理
}
double angleT(NODE O1,NODE O2) //求角t
{
NODE O1O2 = Vector(O1, O2);
return atan2(O1O2.y, O1O2.x); //atan2(double y,double x) 计算向量O1O2与x轴的夹角 范围(-pi,pi]
}
inline NODE Vector(NODE A, NODE B)
{
return{ B.x - A.x, B.y - A.y };
}
inline double dis2(NODE a, NODE b)
{
return (b.x-a.x)*(b.x-a.x) + (b.y-a.y)*(b.y-a.y);
}
参考书籍: 挑战程序设计竞赛2