[計算幾何] 圓與圓的交點座標

給出兩圓的圓心座標和半徑, 求出兩圓交點的座標

 

如下圖

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章