rt
#include<bits/stdc++.h>
using namespace std;
#define db long double
const db eps=1e-9,pi=acos(-1);
pair<db,db>ercifangcheng(db a,db b,db c){return{(-b+sqrt(b*b-4*a*c))/2/a,(-b-sqrt(b*b-4*a*c))/2/a};}
struct Point{db x,y;}A,B;
bool operator==(Point a,Point b){return abs(a.x-b.x)<=eps&&abs(a.y-b.y)<=eps;}
bool operator!=(Point a,Point b){return abs(a.x-b.x)>eps||abs(a.y-b.y)>eps;}
bool operator<(Point a,Point b){return abs(a.x-b.x)<=eps?a.y<b.y:a.x<b.x;}
bool IsNumber(Point A){return-1e18<A.x&&A.x<1e18&&-1e18<A.y&&A.y<1e18;}
struct Vector{Point s,e;};
db cross(Vector a,Vector b){return(a.s.x-a.e.x)*(b.s.y-b.e.y)-(a.s.y-a.e.y)*(b.s.x-b.e.x);}
db dis(Point a,Point b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
db sqdis(Point a,Point b){return(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}
db len(Point a,Point b,Point c){return cross({a,b},{a,c})/dis(a,b);}
db qingxiejiao(Point a,Point b){return atan((a.y-b.y)/(a.x-b.x));}
bool OnOneLine(Point a,Point b,Point c){return abs(cross({a,b},{a,c}))<=eps;}
bool OnCircle(Point O,db r,Point P){return abs(sqdis(O,P)-r*r)<=eps;}
bool InCircle(Point O,db r,Point P){return sqdis(O,P)<r*r;}
bool OutCircle(Point O,db r,Point P){return sqdis(O,P)>r*r;}
Point zhongdian(Point A,Point B){return{(A.x+B.x)/2,(A.y+B.y)/2};}
Point zhixianjiaodian(Point A,Point B,Point C,Point D){
db a1=A.y-B.y,b1=B.x-A.x,c1=A.x*(A.y-B.y)-A.y*(A.x-B.x),a2=D.y-C.y,b2=C.x-D.x,c2=D.x*(D.y-C.y)-D.y*(D.x-C.x);
return{(c1*b2-c2*b1)/(a1*b2-a2*b1),(a1*c2-a2*c1)/(a1*b2-a2*b1)};
}Point chuizu(Point A,Point B,Point P){
db k=sqrt(sqdis(A,P)-len(A,B,P)*len(A,B,P))/dis(A,B);
return{A.x+(B.x-A.x)*k,A.y+(B.y-A.y)*k};
}Point chuixian(Point A,Point B,Point P){
if(OnOneLine(A,B,P))return P==A?(Point){P.x+B.y-P.y,P.y-B.x+P.x}:(Point){P.x+A.y-P.y,P.y-A.x+P.x};
else return chuizu(A,B,P);
}Point waixin(Point A,Point B,Point C){
Point midAB=zhongdian(A,B),midBC=zhongdian(B,C);
return zhixianjiaodian(midAB,chuixian(A,B,midAB),midBC,chuixian(B,C,midBC));
}Point neixin(Point A,Point B,Point C){
db k1=1/dis(A,B),k2=1/dis(B,C),k3=1/dis(A,C);
Point P1={A.x+k1*(B.x-A.x),A.y+k1*(B.y-A.y)},P2={A.x+k3*(C.x-A.x),A.y+k3*(C.y-A.y)},midP=zhongdian(P1,P2),Q1={B.x+k2*(C.x-B.x),B.y+k2*(C.y-B.y)},Q2={B.x+k1*(A.x-B.x),B.y+k1*(A.y-B.y)},midQ=zhongdian(Q1,Q2);
return zhixianjiaodian(midP,chuixian(P1,P2,midP),midQ,chuixian(Q1,Q2,midQ));
}pair<Point,Point>yuanxianjiaodian(Point O,db r,Point P,Point Q){
db a1=-2*O.x,b1=-2*O.y,c1=r*r-O.x*O.x-O.y*O.y,A=Q.y-P.y,B=P.x-Q.x,C=P.x*Q.y-P.y*Q.x;
if(abs(A)<=eps){
db y=C/B;pair<db,db>x=ercifangcheng(1,a1,y*y+b1*y-c1);
return{{x.first,y},{x.second,y}};
}else{
db u=1+B/A*B/A,v=b1-2*B/A*C/A-a1/A*B,w=C/A*C/A+a1/A*C-c1;
pair<db,db>y=ercifangcheng(u,v,w),x={(C-B*y.first)/A,(C-B*y.second)/A};
return{{x.first,y.first},{x.second,y.second}};
}
}pair<Point,Point>yuanjiaodian(Point O1,db r1,Point O2,db r2){
db a1=-2*O1.x,b1=-2*O1.y,c1=r1*r1-O1.x*O1.x-O1.y*O1.y,a2=-2*O2.x,b2=-2*O2.y,c2=r2*r2-O2.x*O2.x-O2.y*O2.y,A=a1-a2,B=b1-b2,C=c1-c2;
if(abs(A)<=eps){
db y=C/B;pair<db,db>x=ercifangcheng(1,a1,y*y+b1*y-c1);
return{{x.first,y},{x.second,y}};
}else{
db u=1+B/A*B/A,v=b1-2*B/A*C/A-a1/A*B,w=C/A*C/A+a1/A*C-c1;
pair<db,db>y=ercifangcheng(u,v,w),x={(C-B*y.first)/A,(C-B*y.second)/A};
return{{x.first,y.first},{x.second,y.second}};
}
}pair<pair<Point,Point>,pair<Point,Point>>pingyi(Point A,Point B,db l){
db k=l/dis(A,B),y=B.y-A.y,x=B.x-A.x;
return{{{A.x+k*y,A.y-k*x},{B.x+k*y,B.y-k*x}},{{A.x-k*y,A.y+k*x},{B.x-k*y,B.y+k*x}}};
}
char s[50];
int main(){
while(~scanf("%s",s)){
int L=strlen(s);
if(L==19){
db x1,y1,x2,y2,x3,y3;cin>>x1>>y1>>x2>>y2>>x3>>y3;
Point ans=waixin({x1,y1},{x2,y2},{x3,y3});db d=dis(ans,{x1,y1});
printf("(%.6Lf,%.6Lf,%.6Lf)\n",ans.x,ans.y,d);
}if(L==15){
db x1,y1,x2,y2,x3,y3;cin>>x1>>y1>>x2>>y2>>x3>>y3;
Point ans=neixin({x1,y1},{x2,y2},{x3,y3});db d=len({x1,y1},{x2,y2},ans);
printf("(%.6Lf,%.6Lf,%.6Lf)\n",ans.x,ans.y,d);
}if(L==23){
db xc,yc,r,xp,yp;cin>>xc>>yc>>r>>xp>>yp;
if(InCircle({xc,yc},r,{xp,yp}))puts("[]");
if(OnCircle({xc,yc},r,{xp,yp})){
db th=qingxiejiao({xp,yp},chuixian({xp,yp},{xc,yc},{xp,yp}));if(th<0)th+=180;
printf("[%.6Lf]\n",th);
}if(OutCircle({xc,yc},r,{xp,yp})){
pair<Point,Point>ans=yuanjiaodian({xc,yc},r,zhongdian({xp,yp},{xc,yc}),dis({xp,yp},{xc,yc})/2);
db th1=qingxiejiao(ans.first,{xp,yp})/pi*180,th2=qingxiejiao(ans.second,{xp,yp})/pi*180;
if(th1<0)th1+=180;if(th2<0)th2+=180;if(th1>th2)swap(th1,th2);
printf("[%.6Lf,%.6Lf]\n",th1,th2);
}
}if(L==46){
db xp,yp,x1,y1,x2,y2,r;cin>>xp>>yp>>x1>>y1>>x2>>y2>>r;
pair<pair<Point,Point>,pair<Point,Point>>line=pingyi({x1,y1},{x2,y2},r);
pair<Point,Point>ans1=yuanxianjiaodian({xp,yp},r,line.first.first,line.first.second),ans2=yuanxianjiaodian({xp,yp},r,line.second.first,line.second.second);
vector<Point>ans;int use[4]={1,1,1,1};
if(IsNumber(ans1.first))ans.push_back(ans1.first);if(IsNumber(ans1.second))ans.push_back(ans1.second);if(IsNumber(ans2.first))ans.push_back(ans2.first);if(IsNumber(ans2.second))ans.push_back(ans2.second);
sort(ans.begin(),ans.end()),putchar('[');
for(int i=0;i<(int)ans.size()-1;i++)if(ans[i]==ans[i+1])use[i]=0;
for(int i=0;i<ans.size();i++)if(use[i]){
printf("(%.12Lf,%.12Lf)",ans[i].x,ans[i].y);
if(i!=ans.size()-1)printf(",");
}puts("]");
}
}
return 0;
}
86~98行(UVA12304第4问),跑
CircleThroughAPointAndTangentToALineWithRadius 100 200 75 190 185 65 100
CircleThroughAPointAndTangentToALineWithRadius 75 190 75 190 185 65 100
CircleThroughAPointAndTangentToALineWithRadius 100 300 100 100 200 100 100
CircleThroughAPointAndTangentToALineWithRadius 100 300 100 100 200 100 99
掉精了。