Mindis(圆的反演变换)

题意:

圆心 O 坐标(0, 0), 给定两点 P, Q(不在圆外),满足 PO = QO, 要在圆上找一点 D,使得 PD + QD 取到最小值。

官方题解:

 

做P点关于圆的反演点P',OPD与ODP'相似,相似比是|OP| : r。

Q点同理。

极小化PD+QD可以转化为极小化P'D+Q'D。

当P'Q'与圆有交点时,答案为两点距离,否则最优值在中垂线上取到。

时间复杂度 O(1)

O(1)

 

反演的定义:

已知一圆C,圆心为O,半径为r,如果P与P’在过圆心O的直线上,且,则称P与P'关于O互为反演。

反演的性质:

除反演中心外,平面上的每一个点都只有唯一的反演点,且这种关系是对称的,位于反演圆上的点,保持在原处,位于

反演圆外部的点,变为圆内部的点,位于反演圆内部的点,变为圆外部的点。 举个最简单的例子,区间以1为反演

半径,那么反演后的区间就是,这就是一维反演,而圆的反演是二维反演。

P向圆反演后的到P',可以推出P'DO 与 PDO是相似三角形,那么PD的距离就可以通过P'D来算

Q点同理。

当 P'Q' 与圆有交点时:

不妨设交点为 O',若 D 不为 O',则 P'D + Q'D >  P'Q'(三角形两边之和大于第三边);当且仅当 D 取 O' 时,P'Q + Q'D 取到最小值,即为 P'Q'。

当 P'Q' 与圆无交点时:

不妨将 P' 与 Q' 看成椭圆的两个焦点,当椭圆慢慢变大时,第一个碰到的圆上的点 D 即为使得 P'D + Q'D 最小的点;画个图就很显然了,第一个碰到的点即为 PQ 的中垂线与圆的交点。

至于判断有 P'Q' 与圆有没有交点,就是圆心到直线的距离与半径比较,又因为此处 P'O=Q'O,所以只需要比较 P'Q' 的中点到圆心的距离和半径的大小。

#include<bits/stdc++.h>
#define eps 1e-6
using namespace std;


int main()
{
    //std::ios::sync_with_stdio(false);
    //std::cin.tie(0);
    double x1,y1,x2,y2,r,ans,dist;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lf%lf%lf%lf%lf",&r,&x1,&y1,&x2,&y2);
        double d=sqrt(x1*x1 + y1*y1);
        if(d<eps)
        {
            printf("%.7lf\n",2*r);
            continue;
        }
        double k=(r*r)/(d*d); //    Q这个点反演点与他到圆心的比例
        double x3=x1*k,y3=y1*k,x4=x2*k,y4=y2*k;
        double ox=(x3+x4)/2,oy=(y3+y4)/2; //P,Q中点坐标
        double dis=sqrt(ox*ox + oy*oy);
        if(dis <= r)
        {
            dist=sqrt((x3-x4)*(x3-x4) + (y3-y4)*(y3-y4));
            ans=dist*d/r;
            printf("%.7lf\n",ans);
        }
        else
        {
            dis=dis-r;
            double temp=sqrt((x3-x4)*(x3-x4) + (y3-y4)*(y3-y4))/2;
            dist=sqrt(temp*temp + dis*dis );
            ans=(dist +dist)*d/r;
            printf("%.7lf\n",ans);
        }
    }
}

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值