用户工具

站点工具


2020-2021:teams:legal_string:王智彪:反演

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
2020-2021:teams:legal_string:王智彪:反演 [2021/08/05 01:21]
王智彪
2020-2021:teams:legal_string:王智彪:反演 [2021/08/06 18:33] (当前版本)
王智彪
行 22: 行 22:
  
 两个图形相切,他们的反演图形也相切。 两个图形相切,他们的反演图形也相切。
 +
 +===== 算法实现 =====
 +
 +<hidden 实现>
 +
 +<code cpp>
 +
 +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;
 +
 +
 +</​code>​
 +
 +</​hidden>​
  
 ===== 代码练习 ===== ===== 代码练习 =====
2020-2021/teams/legal_string/王智彪/反演.1628097664.txt.gz · 最后更改: 2021/08/05 01:21 由 王智彪