分析:给你n边形的坐标、圆心坐标和半径,问你这n边形是不是凸多边形,如果不是输出:HOLE IS ILL-FORMED,否则,如果圆在凸包内就输出:PEG WILL FIT,否则输出:PEG WILL NOT FIT。因为这n边形的坐标是按顺时针或逆时针给出的,所以判断时只有看每相邻两边的叉积符号是否相同,不同的话就不是凸包。在判断圆心是否在凸包内,这个也好判断,也是看叉积符号是否一致,再判断有没有相交,只要看圆心到直线的距离和半径的比较。
# include <stdio.h>
# include <math.h>
struct point
{
double x,y;
}v[1005];
double Dot(point a,point b,point c)// ab·ac
{
return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y);
}
double Cross(point a,point b,point c)// abxac
{
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
double Len(point a,point b)// |ab|
{
return sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y));
}
double Dis(point p,point a,point b)// p到直线ab的距离
{
return fabs(Cross(p,a,b))/Len(a,b);
}
int Convex(int n)// 判断凸包
{
int i;
double f=Cross(v[0],v[1],v[2]);
for(i=1;i<n;i++)
if(f*Cross(v[i],v[(i+1)%n],v[(i+2)%n])<0)
break;
return i<n?0:1;
}
int Contain(point p,int n)// 判断p是否在凸包内
{
int i;
double f=Cross(v[0],v[1],p);
for(i=1;i<n;i++)
if(f*Cross(v[i],v[(i+1)%n],p)<0)
break;
return i<n?0:1;
}
int main()
{
int i,n,f,t=1;
double r;
point p;
while(scanf("%d",&n)!=EOF)
{
if(n<3)
break;
scanf("%lf%lf%lf",&r,&p.x,&p.y);
for(i=0;i<n;i++)
scanf("%lf%lf",&v[i].x,&v[i].y);
if(!Convex(n))
printf("HOLE IS ILL-FORMED\n");
else if(!Contain(p,n))
printf("PEG WILL NOT FIT\n");
else
{
for(i=0;i<n;i++)
if(Dis(p,v[i],v[(i+1)%n])<r)
break;
if(i<n)
printf("PEG WILL NOT FIT\n");
else
printf("PEG WILL FIT\n");
}
}
return 0;
}