题意:有一个圆心在原点,半径为
r
的圆,圆内有两点
当然不是直接取中垂线这么简单啊……
反演点:
已知圆 O 的半径为R ,从圆心 O 出发任作一射线,在射线上任取两点M,N 。若 |OM|=m , |ON|=n ,且 m∗n=R2 ,则称点 M,N 是关于圆 O 的反演点。M,N 关于圆 O 的一个变换叫做反演变换。——百度百科
所以就是延长
所以
P′Q′
这条直线和圆有交点的时候,当然是取交点为
D
啦。否则的话,就是中垂线和圆的交点为
放两个从网上盗的图。
#include <bits/stdc++.h>
using namespace std;
const double eps=1e-8;
int T;
double r,X1,Y1,X2,Y2;
int main(){
scanf("%d",&T);
while (T--){
scanf("%lf %lf %lf %lf %lf",&r,&X1,&Y1,&X2,&Y2);
double d0=sqrt(X1*X1+Y1*Y1);
if (fabs(d0)<eps){
printf("%.7f\n",2*r);
continue;
}
double k=(r*r)/(d0*d0);
double xx1=k*X1,yy1=k*Y1,xx2=k*X2,yy2=k*Y2;
double mx=(xx1+xx2)/2.0;
double my=(yy1+yy2)/2.0;
double d=sqrt(mx*mx+my*my);
double ans=0;
if (d<=r){
double dist=sqrt((xx1-xx2)*(xx1-xx2)+(yy1-yy2)*(yy1-yy2));
ans=dist*d0/r;
}
else{
double tx,ty;
tx=mx*r/d;
ty=my*r/d;
ans=2*sqrt((tx-X1)*(tx-X1)+(ty-Y1)*(ty-Y1));
}
printf("%.7f\n",ans);
}
}