[计算几何] 圆与圆的交点坐标

给出两圆的圆心坐标和半径, 求出两圆交点的坐标

如下图

 可根据余弦定理求出角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

猜你喜欢

转载自blog.csdn.net/Mr_HCW/article/details/82861431