点到线段的最短距离

#include<bits/stdc++.h>
using namespace std;
const int M = 1e5+10 ;
const double pi = acos(-1.0) ;
int n ;
double sx , sy ;//源点
double X[M] , Y[M] ;
double minn = 1e18 , maxn = -1 ;

double dist (int id) { return sqrt((X[id]-sx)*(X[id]-sx)+(Y[id]-sy)*(Y[id]-sy));} 

double segdist (int id1 , int id2) {//源点到多边形上两点id1,id2的最短距离
    double a = Y[id2] - Y[id1] ;
    double b = X[id1] - X[id2] ;
    double c = X[id2]*Y[id1]-Y[id2]*X[id1] ;

    if ((X[id1]-X[id2])*(sx-X[id2])+(Y[id1]-Y[id2])*(sy-Y[id2]) < 0) return 1e18 ;//如果垂足落在线段外,返回无穷
    if ((X[id2]-X[id1])*(sx-X[id1])+(Y[id2]-Y[id1])*(sy-Y[id1]) < 0) return 1e18;//利用点积钝角<0

    return fabs(c+sy*b+sx*a) / sqrt(a*a+b*b) ; //利用叉积和面积法
}

int main () {
    cin >> n >> sx >> sy ;
    for (int i = 0 ; i < n ; i ++) {
        scanf ("%lf%lf" , &X[i],&Y[i]) ;
    }
    for (int i = 0 ; i < n ; i ++) {
        maxn = max (maxn , dist(i)) ;
        minn = min (minn , dist(i)) ;//垂足落在线段外时,源点到线段的最短距离

        minn = min (minn , segdist(i,(i+1)%n)) ;
    }
    cout.precision(12) ;
    cout << pi*(maxn*maxn-minn*minn) << endl ;
    return 0 ;
}

  

转载于:https://www.cnblogs.com/get-an-AC-everyday/p/5134502.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值