/*
判断凸包 + 点到直线距离
http://poj.org/problem?id=1584
给出n个点 和一个圆心坐标和半径
判断是不是凸包,如果是,判断圆在不在凸包里
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
using namespace std ;
#define eps 1e-8
struct node{
double x , y ;
}p[10005] , q ;
double r , r_x , r_y ;
node sub(node a,node b)
{
a.x -= b.x ;
a.y -= b.y ;
return a ;
}
int mul(node a,node b)
{
if( a.x*b.y - a.y*b.x >= 0 )
return 1 ;
else
return -1 ;
}
//ab直线到圆心q的距离
double dis(node a,node b)
{
if( fabs(a.x-b.x) < eps )
return fabs(q.x-a.x) ;
else if( fabs(a.y-b.y) < eps )
return fabs(q.y-a.y) ;
else
{
node s , e ;
s = sub(a,b) ;
e = sub(q,b) ;
return fabs(s.x*e.y-s.y*e.x)/( sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) ) );
}
}
int main()
{
int n , i , j , flag ;
while( scanf("%d", &n) && n >= 3 )
{
scanf("%lf %lf %lf", &r, &q.x, &q.y) ;
for(i = 0 ; i < n ; i++)
scanf("%lf %lf", &p[i].x, &p[i].y) ;
//判断是不是凸包
p[n] = p[0];
flag = mul(sub(p[1],p[0]),sub(p[2],p[1])) ;
for(i = 1 ; i < n ; i++)
{
/*如果图形是凸包,对任意连续三个点a,b,c的叉乘(b-a,c-b)的正负相同,
也就是说在同一边,这样就可以判断凸包。*/
if( flag != mul(sub(p[i],p[i-1]),sub(p[i+1],p[i]) ) )
break ;
}
if( i < n )
{
printf("HOLE IS ILL-FORMED\n") ;
continue ;
}
for(i = 0 ; i < n ; i++)
{
//圆心在不在凸包
if( flag != mul( sub(p[i+1],p[i]),sub(q,p[i]) ) )
break ;
//两点所在直线到圆心的距离与r的大小
if( dis(p[i],p[i+1]) - r < 0 )
break ;
}
if( i < n )
printf("PEG WILL NOT FIT\n") ;
else
printf("PEG WILL FIT\n") ;
}
return 0;
}
凸包判断 + 点到直线距离--poj1584
最新推荐文章于 2023-09-28 01:41:23 发布