码迷,mamicode.com
首页 > 其他好文 > 详细

【计算几何】【圆反演】hdu6097 Mindis

时间:2017-08-16 23:16:04      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:using   min   details   read   csdn   names   pac   计算   net   

给你一个中心在原点的圆,再给你俩在圆内且到原点距离相等的点P,Q,让你在圆上求一点D,最小化DP+DQ。

http://blog.csdn.net/qq_34845082/article/details/77099332

附:过反演中心的圆反演后变成一条和该圆正交的直线。

不过反演中心的圆反演后是一个与原圆关于反演中心位似的圆。

不过反演中心的直线反演后变成一个过反演中心且与其正交的圆。

#include<cstdio>
#include<cmath>
using namespace std;
const double EPS=0.0000000001;
struct Point{
    double x,y;
    Point(){}
    Point(const double &x,const double &y){
        this->x=x;
        this->y=y;
    }
    double length(){
        return sqrt(x*x+y*y);
    }
    void read(){
        scanf("%lf%lf",&x,&y);
    }
}p,q;
double R;
typedef Point Vector;
Vector unit(Vector v){
    double l=v.length();
    return Vector(v.x/l,v.y/l);
}
Point CalcMid(const Point &a,const Point &b){
    return Point((a.x+b.x)*0.5,(a.y+b.y)*0.5);
}
double sqr(const double &x){
    return x*x;
}
Vector operator - (const Point &a,const Point &b){
    return Vector(a.x-b.x,a.y-b.y);
}
Vector operator * (const double &K,const Vector &v){
    return Vector(K*v.x,K*v.y);
}
int T;
int main(){
    scanf("%d",&T);
    for(;T;--T){
        scanf("%lf",&R);
        p.read();
        q.read();
        if(fabs(p.x)<EPS && fabs(p.y)<EPS){
            printf("%.10lf\n",2.0*R);
            continue;
        }
        Point mp=CalcMid(p,q);
        Point P=Point((p-mp).length(),sqrt(sqr(p.length())-sqr((p-mp).length())));
        Point Pp=R*R/P.length()*unit(P);
        if(Pp.y-R>EPS){
            printf("%.10lf\n",P.length()/R*2.0*(Pp-Point(0.0,R)).length());
        }
        else{
            printf("%.10lf\n",P.length()/R*2.0*Pp.x);
        }
    }
    return 0;
}

【计算几何】【圆反演】hdu6097 Mindis

标签:using   min   details   read   csdn   names   pac   计算   net   

原文地址:http://www.cnblogs.com/autsky-jadek/p/7376243.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!