计算圆与圆的交点,需要用到余弦定理
步骤如下:
- 求出两个圆的圆心距d
- 求出向量c2.c-c1.c与c1.c到某交点的向量夹角a
- 求出向量c2.c-c1.c与x轴的夹角t
- 那么,两个交点就分别是以c1.c为起点,大小为c1.r,角度为t+a、t-a的两个向量
题目:CGL_7_E
AC代码:
#include <iostream>
#include <cstdio>
#include <math.h>
using namespace std;
#define COUNTER_CLOCKWISE -1 //逆时针
#define CLOCKWISE 1 //顺时针
#define ONLINE_BACK -2 //p2 p0 p1依次排列在一条直线上
#define ONLINE_FRONT 2 //p0 p1 p2依次排列在一条直线上
#define ON_SEGMENT 0 //p2在线段p0p1上
#define EPS 1E-8
class Point
{
public:
double x, y;
Point()
{
}
Point(double x, double y)
{
(*this).x = x;
(*this).y = y;
}
double operator^(const Point &p) const //叉乘
{
return x * p.y - y * p.x;
}
double operator*(const Point &p) const //点乘
{
return x * p.x + y * p.y;
}
Point operator*(const double &d) const
{
return Point(x * d, y * d);
}
Point operator/(const double &d) const
{
return Point(x / d, y / d);
}
Point operator-(const Point &p) const
{
return Point(x - p.x, y - p.y);
}
Point operator+(const Point &p) const
{
return Point(x + p.x, y + p.y);
}
double sqr()
{
return x * x + y * y;
}
double abs()
{
return sqrt(sqr());
}
double distance(const Point &p)
{
return fabs((*this - p).abs());
}
void print()
{
printf("%.8lf %.8lf", x, y);
}
};
class Line
{
public:
Point p1, p2;
Point vec;
Line()
{
}
Line(Point p1, Point p2)
{
(*this).p1 = p1;
(*this).p2 = p2;
(*this).vec = p2 - p1;
}
};
class Circle
{
public:
Point o;
double r;
Circle()
{
}
Circle(Point o, double r)
{
(*this).o = o;
(*this).r = r;
}
Circle(double cx, double cy, double r)
{
(*this).o.x = cx;
(*this).o.y = cy;
(*this).r = r;
}
};
Point polar(double length, double angle) //根据模长、角度求向量
{
return Point(length * cos(angle), length * sin(angle));
}
pair<Point, Point> get_Cross_Points(Circle c1, Circle c2) //求圆与圆的交点
{
Point vec12 = c2.o - c1.o; //两圆圆心的向量
double d = vec12.abs(); //圆心距
double a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2.0 * c1.r * d)); //vec12与(c1与一个交点)的夹角
double t = atan2(vec12.y, vec12.x); //vec12与x轴的夹角
return make_pair(c1.o + polar(c1.r, t + a), c1.o + polar(c1.r, t - a));
}
int main()
{
Circle c1, c2;
cin >> c1.o.x >> c1.o.y >> c1.r;
cin >> c2.o.x >> c2.o.y >> c2.r;
auto ans = get_Cross_Points(c1, c2);
if (ans.first.x < ans.second.x)
{
ans.first.print();
cout << ' ';
ans.second.print();
cout << endl;
}
else if (ans.second.x < ans.first.x)
{
ans.second.print();
cout << ' ';
ans.first.print();
cout << endl;
}
else
{
if (ans.first.y - ans.second.y <= EPS)
{
ans.first.print();
cout << ' ';
ans.second.print();
cout << endl;
}
else
{
ans.second.print();
cout << ' ';
ans.first.print();
cout << endl;
}
}
}
转载请注明来源:https://www.longjin666.top/?p=802
欢迎关注我的公众号“灯珑”,让我们一起了解更多的事物~