题目来源:

http://poj.org/problem?id=1584

 

题意: 给一个多边形, 一个圆心以及半径。 首先判断是否为凸多边形。 如果是凸多边形, 再判断,圆是否在凸多边形内部。

分析:

1) 先判断是否为凸多边形 ,题目给出的顶点是有序的, 即顺时针或是 逆时针。用叉积方向判断。

2) 判断圆在多边形内, 首先判断 圆心是否在多边形内部, 是的话,然后再 判断 圆心到多边形 所有边的 距离d >= r , 即可。

代码如下:

const int Max_N = 1005;
const double EPS = 1e-10 ;
//---------凸包----
double add(double a, double b){
    return (fabs(a + b) < EPS * (fabs(a) + fabs(b))) ? 0 : (a + b) ;
}
struct Point{
    double x  , y ;
    Point(){}
    Point(double x, double y):x(x),y(y){}
    double dist(Point p){
        return sqrt(add((x - p.x)*(x - p.x) ,(y - p.y )*(y - p.y) )) ;
    }
    Point operator -(Point p){
        return Point( add(x ,- p.x) , add( y, - p.y) ) ;
    }
    double operator ^(Point p){
        return add(x * p.y ,- y * p.x );
    }
};
Point List[Max_N] ;
int n;
//判断是否为 凸包
bool is_convex(){
    int i , left = 0, right = 0;
    List[n] = List[0] ;
    List[n+1] = List[1] ;
    for(i = 0 ; i < n ; i++){
        if( ((List[i+1] - List[i])^(List[i+2] - List[i+1])) < 0)
            right ++ ;
        else if(((List[i+1] - List[i])^(List[i+2] - List[i+1])) > 0)
            left ++ ;
    }
    if(right==0 || left == 0)
        return 1 ;
    return 0;
}
Point ro;
double r;
//判断圆心是否在凸包内或凸包边上,在凸包上或内返回1
int inside_convex(){
    int i, left = 0 , right = 0;
    for(i = 0 ;  i < n ; i++){
        double d = (ro- List[i])^(List[(i+1)%n] - List[i]) ;
        if(d > 0) left ++;
        if(d < 0) right ++ ;
    }
    if(left == 0 || right == 0)
        return 1;
    return 0 ;
}
// 计算点p到直线p1p2的最短距离
double dist_ptoseg(Point p, Point p1, Point p2){
    return  fabs((p1-p)^(p2-p)) / (p1.dist(p2)) ;
}
//判断圆是否在凸多边形内
int cicle_in_convex(){
    int i  ;
    List[n] = List[0] ;
    for(i = 0 ; i< n ; i++){
        if(dist_ptoseg(ro , List[i] , List[i+1])  < r )
            return 0 ;
    }
    return 1;
}

int main()
{
    while(scanf("%d" , &n) && n >= 3){
        scanf("%lf%lf%lf", &r , &ro.x, &ro.y) ;
        for(int i=0 ; i < n ; i++){
            scanf("%lf%lf" , &List[i].x , &List[i].y) ;
        }
        if(!is_convex())
            puts("HOLE IS ILL-FORMED");
        else{
            if(inside_convex() && cicle_in_convex()){
                puts("PEG WILL FIT") ;
            }
            else
                puts("PEG WILL NOT FIT") ;
        }
    }
}