两圆交点
https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_E
int sgn(double x) {
if(fabs(x)<eps)return 0;
return x<0?-1:1;
}
struct Point { //定义点和基本运算
double x,y;
double ang;
Point() {}
Point(double x,double y):x(x),y(y) {}
Point operator + (Point B) {
return Point(x+B.x,y+B.y);
}
Point operator - (Point B) {
return Point(x-B.x,y-B.y);
}
Point operator * (double k) {
return Point(x*k,y*k); //长度增大k倍
}
Point operator / (double k) {
return Point(x/k,y/k); //长度缩小k倍
}
bool operator == (Point B) {
return sgn(x-B.x)==0 && sgn(y-B.y)==0;
}
double operator ^(Point B) {
return x*B.y-y*B.x;
}
double distance(Point p) {
return hypot(x-p.x,y-p.y);
}
};
typedef Point Vector;
double Cross(Vector A,Vector B) {
return A.x*B.y - A.y*B.x; //叉积
}
struct Line {
Point p1,p2;//线上的两个点
Line() {}
Line(Point p1,Point p2):p1(p1),p2(p2) {}
};
struct Circle {
Point c;//圆心
double r;//半径
Circle() {}
Circle(Point c,double r):c(c),r(r) {}
Circle(double x,double y,double _r) {
c=Point(x,y);
r = _r;
}
Point point(double ang) { //圆上与圆心极坐标为ang的点
return Point(c.x+cos(ang)*r,c.y+sin(ang)*r);
}
};
double Distance(Point A, Point B) {
return hypot(A.x-B.x,A.y-B.y);
}
//求向量v的极角
double angle(Vector v) {
return atan2(v.y,v.x);
}
int getcirclecirclePoint(Circle c1,Circle c2,Point &p1,Point &p2) {
double d = Distance(c1.c,c2.c);
if(sgn(d)== 0) {
if(sgn(c1.r-c2.r)==0)return -1; //重合
return 0; //没有交点
}
if(sgn(c1.r+c2.r-d)<0)return 0; //相离
if(sgn(fabs(c1.r-c2.r)-d)>0)return 0; //内含
double a =angle(c2.c-c1.c); //c1->c2的极角
double da=acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2*c1.r*d));
p1=c1.point(a-da),p2=c1.point(a+da);
if(p1==p2)return 1;
else return 2;
}
void work() {
Circle a,b;
scanf("%lf%lf%lf",&a.c.x,&a.c.y,&a.r);
scanf("%lf%lf%lf",&b.c.x,&b.c.y,&b.r);
Point p1,p2;
int t= getcirclecirclePoint(a,b,p1,p2);
if(sgn(p1.x-p2.x)>0)swap(p1,p2);
else if(sgn(p1.x-p2.x)==0&&sgn(p1.y-p2.y)>0)swap(p1,p2);
printf("%lf %lf ",p1.x,p1.y);
printf("%lf %lf\n",p2.x,p2.y);
}