struct Inversion {
Point o;//反演中心
double r;//反演半径
Inversion() {}
Inversion(Point _o,double _r) {
o=_o;
r=_r;
}
//点的反演 flag为0获取失败 1获取成功
void getPointInv(Point a,Point &aa,int &flag) {
if(a==o) {
flag=0;
aa=a;
return;
}
Point ptmp=a-o;
double len=ptmp.len();
ptmp=ptmp.trunc(r*r/len);
aa=o+ptmp;
flag=1;
}
//圆的反演 flag为1变成圆 -1变成直线
void getCircleInv(circle c,Line &l,circle &cc,int &flag) {
if(c.relation(o)^1) {
Point p1,p2,pp1,pp2;
Line lt;
flag=1;
if(c.p==o) {
cc.p=o;
cc.r=r*r/c.r;
return;
}
lt=Line(c.p,o);
int ii=c.pointcrossline(lt,p1,p2);
int f;
getPointInv(p1,pp1,f);
getPointInv(p2,pp2,f);
Point pp=(pp1+pp2)/2;
cc.p=pp;
cc.r=pp1.distance(pp2)/2;
return;
}
flag=-1;
Point ptmp=c.p*2-o,pptmp,p1,p2;
int f;
getPointInv(ptmp,pptmp,f);
p1=o-pptmp;
p1=p1.rotleft();
p1=p1+pptmp;
l=Line(pptmp,p1);
}
//直线的反演 成圆
void getLineInv(Line L,circle &cc,int &flag) {
if(L.relation(o)==3) {
flag=0;
return;
}
flag=1;
Point p=L.lineprog(o),ans;
int f;
getPointInv(p,ans,f);
cc.r=ans.distance(o)/2;
cc.p=(ans+o)/2;
}
} iv;