計算幾何 點到線段的距離 點在簡單多邊形內 點到凸多邊形的距離
阿新 • • 發佈:2018-12-24
#include <bits/stdc++.h> using namespace std; struct point_t { double x,y; }; double cross(point_t const &O,point_t const &A,point_t const &B){ double xOA = A.x - O.x; double yOA = A.y - O.y; double xOB = B.x - O.x; double yOB = B.y - O.y; return xOA * yOB - xOB * yOA; } double PointTOline( point_t const&a,point_t const&b,point_t const&p){ double ap_ab = (b.x - a.x)*(p.x - a.x)+(b.y - a.y)*(p.y - a.y);//cross( a , p , b ); if ( ap_ab <= 0 ) return sqrt( (p.x-a.x)*(p.x-a.x) + (p.y-a.y)*(p.y-a.y) ); double d2 = ( b.x - a.x ) * ( b.x - a.x ) + ( b.y-a.y ) * ( b.y-a.y ) ; if ( ap_ab >= d2 ) return sqrt( (p.x - b.x )*( p.x - b.x ) + ( p.y - b.y )*( p.y - b.y ) ) ; double r = ap_ab / d2; double px = a.x + ( b.x - a.x ) *r; double py = a.y + ( b.y - a.y ) *r; return sqrt( (p.x - px)*(p.x - px) + (p.y - py)*(p.y - py) ); } bool isOnline( point_t const&a,point_t const&b, point_t const&po ){ return po.x >= min( a.x , b.x ) && po.x <= max( a.x , b.x ) && po.y >= min( a.y , b.y ) && po.y <= max( a.y , b.y ) && ( po.x - a.x ) * ( b.y - a.y ) == ( po.y - a.y ) * ( b.x - a.x ); } bool isInSimple( point_t * p ,int n , point_t const&po ){ p[n] = p[0]; bool flag = 0; int tmp; for ( int i = 0; i < n;++i ){ if ( isOnline( p[i] , p[i+1] , po ) ) return true; if ( p[i].y == p[i+1].y ) continue; p[i].y < p[i+1].y ? tmp = i+1 : tmp = i ; if ( po.y == p[tmp].y && po.x < p[tmp].x ) flag ^= 1; p[i].y > p[i+1].y ? tmp = i+1 : tmp = i ; if ( po.y == p[tmp].y && po.x < p[tmp].x ) continue ; if ( po.x < max( p[i].x , p[i+1].x ) && po.y > min( p[i].y , p[i+1].y ) && po.y < max( p[i].y , p[i+1].y ) ) flag ^= 1; } return flag; } point_t p[120]; int main(){ int n; while(cin>>n && n){ point_t po; cin>>po.x>>po.y; for (int i = 0;i < n;++i) cin>>p[i].x>>p[i].y; if ( isInSimple( p , n , po ) ) { cout <<"0.00"<<endl; continue; } double ans = PointTOline( p[0],p[1],po ); p[n] = p[0]; for (int i = 1;i < n ;++i) ans = min( ans, PointTOline(p[i] , p[i+1] , po) ); cout <<ans<<endl; } return 0; }