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

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

 

如下图

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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
本程序是两相交求交点,输入信息为两圆心坐标半径值。如有更好的算法,欢迎交流!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值