# UVA 12304 2D Geometry 110 in 1！（与圆有关二维几何问题）

MA=(x1-x,y1-y)
MB=(x2-x,y2-y)
MC=(x3-x,y3-y)

∴x=(ax1+bx2+cx3)/(a+b+c),Y=(ay1+by2+cy3)/(a+b+c)
∴O((ax1+bx2+cx3)/(a+b+c),(ay1+by2+cy3)/(a+b+c))

#include<bits/stdc++.h>
using namespace std;
const double PI=acos(-1);
struct Point{
double x,y;
Point(double x=0,double y=0) : x(x),y(y){}
};

typedef Point Vector;
Vector operator +(Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}
Vector operator -(Vector A,Vector B){return Vector(A.x-B.x,A.y-B.y);}
Vector operator *(Vector A,double p){return Vector(A.x*p,A.y*p);}
Vector operator /(Vector A,double p){return Vector(A.x/p,A.y/p);}

bool operator <(const Point& a,const Point &b){
return a.x<b.x || (a.x==b.x && a.y<b.y);
}

const double eps=1e-10;
int dcmp(double x){
if(fabs(x)<eps) return 0;else return x<0?-1 :1;
}

bool operator == (const Point &a,const Point &b){
return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0;}

double dot(Vector A,Vector B){
return A.x*B.x+A.y*B.y;
}

double length(Vector A){return sqrt(dot(A,A));}

Vector normal(Vector A){
double l=length(A);
return Vector(-A.y/l,A.x/l);
}

double todistance(Point x,Point y){
return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
}

}

double cross(Vector A,Vector B){
return A.x*B.y-A.y*B.x;
}

Point getlineintersection(Point p,Vector v,Point q,Vector w){
Vector u=p-q;
double t=cross(w,u)/cross(v,w);
return p+v*t;
}

double distancetoline(Point P,Point A,Point B){
Vector v1=B-A,v2=P-A;
return fabs(cross(v1,v2)/length(v1));
}

struct Line{
Point p;
Vector v;
Line(Point p,Vector v):p(p),v(v){}
Point point(double t){return p+v*t;}
Line move(double d){return Line(p+normal(v)*d,v); }
};

struct Circle{
Point c;
double r;
Circle(){}
Circle(Point c,double r):c(c),r(r){}
}
};

int getlinecircleintersection(Line l,Circle C,double &t1,double &t2,vector<Point>& sol){   //直线和圆相交
double a=l.v.x,b=l.p.x-C.c.x,c=l.v.y,d=l.p.y-C.c.y;
double e=a*a+c*c,f=2*(a*b+c*d),g=b*b+d*d-C.r*C.r;
double delta=f*f-4*e*g;
if(dcmp(delta)<0) return 0; //相离
if(dcmp(delta)==0) {
t1=t2=-f/(2*e); sol.push_back(l.point(t1));
return 1;
}
t1=(-f-sqrt(delta))/(2*e); sol.push_back(l.point(t1));
t2=(-f+sqrt(delta))/(2*e); sol.push_back(l.point(t2));
return 2;

}

//计算向量极角
double angle(Vector v){ return atan2(v.y,v.x);}

double Angle(Vector A,Vector B){
return acos(dot(A,B)/length(A)/length(B));
}
int getcirclecircleintersection(Circle c1,Circle c2,vector<Point> &sol){           //两圆相交
double d=length(c1.c-c2.c);
if(dcmp(d)==0){
if(dcmp(c1.r-c2.r)==0) return -1;  //两圆重合
return 0;
}

if(dcmp(c1.r+c2.r-d)<0) return 0;      //两圆不想交
if(dcmp(fabs(c1.r-c2.r)-d)>0) return 0;

double a=angle(c2.c-c1.c);
double da=acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2*c1.r*d));
Point p1=c1.point(a+da),p2=c1.point(a-da);

sol.push_back(p1);
if(p1==p2) return 1;
sol.push_back(p2);
return 2;

}

int gettangents(Point p,Circle c,vector<double>& v){       //任意一点到圆的切线
Vector u=c.c-p;
double dist=length(u);
if(dist<c.r) return 0;
else if(dcmp(dist-c.r)==0){
v.push_back(angle(rotate(u,PI/2)));
return 1;
} else{
double ang=asin(c.r/dist);
v.push_back(angle(rotate(u,-ang)));
v.push_back(angle(rotate(u,+ang)));
return 2;
}
}

int gettangents(Circle A,Circle B,Point *a,Point *b){
int cnt=0;
if(A.r<B.r) {swap(A,B);swap(a,b);}
int d2=(A.c.x-B.c.x)*(A.c.x-B.c.x)+(A.c.y-B.c.y)*(A.c.y-B.c.y);
int rdiff=A.r-B.r;
int rsum=A.r+B.r;
if(d2<rdiff*rdiff) return 0;      //内含

double base=atan2(B.c.y-A.c.y,B.c.x-A.c.x);
if(d2==0 && A.r==B.r) return -1;              //无限多条
if(d2==rdiff*rdiff){                          //内切，1条切线
a[cnt]=A.point(base);
b[cnt]=B.point(base);
cnt++;
return 1;
}

//有外公切线
double ang=acos((A.r-B.r)/sqrt(d2));
a[cnt]=A.point(base+ang); b[cnt]=B.point(base+ang); cnt++;
a[cnt]=A.point(base-ang); b[cnt]=B.point(base-ang); cnt++;
if(d2==rsum*rsum){
a[cnt]=A.point(base);
b[cnt]=B.point(PI+base);
cnt++;
}
else if(d2>rsum*rsum){
double ang=acos((A.r+B.r)/sqrt(d2));
a[cnt]=A.point(base+ang); b[cnt]=B.point(PI+base+ang);cnt++;
a[cnt]=A.point(base-ang); b[cnt]=B.point(PI+base-ang);cnt++;
}
return cnt;
}

void CircumscribedCircle(){        //1
Point p[3];
for(int i=0;i<3;i++)
scanf("%lf %lf",&p[i].x,&p[i].y);

Point o=getlineintersection((p[0]+p[1])/2,rotate(p[1]-p[0],PI/2),(p[0]+p[2])/2,rotate(p[2]-p[0],PI/2));
printf("(%.6lf,%.6lf,%.6lf)\n",o.x,o.y,todistance(o,p[0]));
}

void InscribedCircle(){
Point p1,p2,p3;
scanf("%lf%lf%lf%lf%lf%lf", &p1.x, &p1.x,&p2.x,&p2.y,&p3.x,&p3.y);
double a=length(p2-p3);
double b=length(p3-p1);
double c=length(p1-p2);
Point p=(p1*a+p2*b+p3*c)/(a+b+c);
printf("(%.6lf,%.6lf,%.6lf)\n",p.x,p.y,distancetoline(p,p1,p2));
}

void TangentLineThroughPoint(){
Circle c;
Point p;
vector<double> v;
scanf("%lf %lf %lf",&c.c.x,&c.c.y,&c.r);
scanf("%lf %lf",&p.x,&p.y);
printf("[");
if(gettangents(p,c,v)){
sort(v.begin(),v.end());
printf("%.6lf",v[1]);
}
if(v.size()==2) printf("%.6lf",v[2]);
printf("]\n");

}

double t1,t2;
Circle c;
Point p1,p2;
scanf("%lf%lf%lf%lf%lf%lf%lf",&c.c.x,&c.c.y,&p1.x,&p1.y,&p2.x,&p2.y,&c.r);

Point a1=p1+normal(p2-p1)*c.r;
Point a2=p1-normal(p2-p1)*c.r;
vector<Point> poi;
poi.clear();
Line l1(a1,p2-p1),l2(a2,p2-p1);
int num=getlinecircleintersection(l1,c,t1,t2,poi);
num+=getlinecircleintersection(l2,c,t1,t2,poi);

printf("[");
for(int i=0;i<num;i++)
{
if(i!=0) printf(",");
printf("(%.6f,%.6f)",poi[i].x,poi[i].y);
}
printf("]\n");
}

inline Point e_to_go(Vector A, double len) { return A / length(A) * len; }

{
Point A, B, C ,D;
double r;
scanf("%lf%lf %lf%lf %lf%lf %lf%lf %lf", &A.x, &A.y, &B.x, &B.y, &C.x, &C.y, &D.x, &D.y, &r);

vector<Point> v;
int control = cross(B - A, D - C) < 0 ? -1 : 1;

Point P = getlineintersection(A, B-A, C, D-C);
double seta = Angle(B - A, D - C)/2;
Vector v1 = rotate(B - A, control*seta);
Vector v2 = rotate(B - A, -control*(PI/2 - seta));

v.push_back(P + e_to_go(v1, r/sin(seta)));
v.push_back(P - e_to_go(v1, r/sin(seta)));
v.push_back(P + e_to_go(v2, r/cos(seta)));
v.push_back(P - e_to_go(v2, r/cos(seta)));
sort(v.begin(), v.end());

for (int i = 0; i < v.size(); i++)
printf("%c(%.6lf,%.6lf)", ",["[i == 0], v[i].x, v[i].y);
printf("]\n");
}

Circle c1,c2;
double r;
scanf("%lf%lf%lf %lf%lf%lf %lf", &c1.c.x, &c1.c.y, &c1.r, &c2.c.x, &c2.c.y, &c2.r, &r);
c1.r += r, c2.r += r;
vector<Point> v;
getcirclecircleintersection(c1,c2,v);
sort(v.begin(), v.end());

if (!v.size())    printf("[");
for (int i = 0; i < v.size(); i++)
printf("%c(%.6lf,%.6lf)", ",["[i == 0], v[i].x, v[i].y);
printf("]\n");
}

string s;
int main(){
while(cin>>s){
if(s=="CircumscribedCircle")
CircumscribedCircle();
else if(s=="InscribedCircle"){
InscribedCircle();
}
else if(s=="TangentLineThroughPoint")
TangentLineThroughPoint();
}
return 0;
}

04-12 628

10-17 17

07-29 10

08-31 46

03-25 665

01-16 4764

10-15 1万+

01-11 3914

06-27 4万+

08-21 1352

04-11 1420

08-09 1万+

04-14 60万+

03-13 15万+

02-19 18万+

03-04 14万+

03-06 3742

03-08 2万+

04-25 7万+

03-10 13万+

03-10 19万+

03-12 11万+

03-13 11万+

03-16 2886

03-18 1万+

03-19 8万+

03-19 4万+

03-20 1万+

03-22 5247

03-23 5万+

03-24 3万+

03-25 3万+

05-08 5万+

03-25 9万+

03-27 5万+

03-29 22万+

03-29 10万+

03-30 17万+

06-01 7239

04-02 6845

04-02 4万+

06-01 878

04-06 1万+

04-06 7万+

04-06 5034

04-09 8万+

04-09 3万+

05-17 9823

04-11 4万+

04-15 6万+

04-18 5万+

04-20 5万+

04-24 3万+

05-03 1万+

05-16 6万+

05-06 2万+

05-06 2532

05-07 4338

05-08 4万+

05-10 4052

05-11 2920

05-14 7518

05-14 1546

05-16 4296

05-16 2万+

05-17 5740

05-30 2795

05-18 2930

05-18 9333

05-18 4388

05-19 1万+

05-21 9012

05-21 9175

05-27 7751

05-30 2089

05-23 7306

05-28 3382

#### 因为无聊，我做出了一个能下载电影、动漫、电视剧的小程序，从此告别过去只能看部分视频简介的历史

©️2019 CSDN 皮肤主题: 深蓝海洋 设计师: CSDN官方博客