题目来源:
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") ;
}
}
}
poj 1584 A Round Peg in a Ground Hole 判断多边形是否为凸多边形 + 圆心是否在凸多边形内
+ 圆是否在凸多边形内部