题意求给出一个多边形,问这个多边形是否是凸包,如果不是数出HOLE IS ILL-FORMED,如果是问一个棍子能否穿过,给出底面的圆心和半径。
分3步:
1、判断是否是凸多边形
2、判断点是否在多边形内部
3、判断点到各边的最小距离是否大于等于半径
由于输入是按照顺时针或者逆时针,所以只要判断相邻叉积同号就可以。。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef double PointType;
struct point
{
PointType x,y;
};
point data[160];
PointType Direction(point pi,point pj,point pk) //判断向量PiPj在向量PiPk的顺逆时针方向 +顺-逆0共线
{
return (pj.x-pi. x)*(pk.y-pi.y)-(pk.x-pi.x)*(pj.y-pi.y);
}
PointType Dis(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int Graham_Scan(point *a,int numa)
{
for(int i=0; i<numa; i++)
if(Direction(a[i],a[(i+1)%numa],a[(i+2)%numa])*Direction(a[(i+1)%numa],a[(i+2)%numa],a[(i+3)%numa])<0)
return 0;
return 1;
}
bool On_Segment(point pi,point pj,point pk)
{
if(pk.x>=min(pi.x,pj.x)&&pk.x<=max(pi.x,pj.x)&&pk.y>=min(pi.y,pj.y)&&pk.y<=max(pi.y,pj.y))
return 1;
return 0;
}
bool Segment_Intersect(point p1,point p2,point p3,point p4)
{
PointType d1=Direction(p3,p4,p1),d2=Direction(p3,p4,p2),d3=Direction(p1,p2,p3),d4=Direction(p1,p2,p4);
if(((d1>0&&d2<0)||(d1<0&&d2>0))&&((d3>0&&d4<0)||(d3<0&&d4>0)))
return 1;
if(d1==0&&On_Segment(p3,p4,p1))
return 1;
if(d2==0&&On_Segment(p3,p4,p2))
return 1;
if(d3==0&&On_Segment(p1,p2,p3))
return 1;
if(d4==0&&On_Segment(p1,p2,p4))
return 1;
return 0;
}
int Pandingdian(point a,int n,point *polygon)//1在多边形上 2在多边形外 0在多边形内
{
point b;
b.x=-9999999;
b.y=a.y;
int sum=0;
polygon[n]=polygon[0];
for(int i=1; i<=n; i++)
if(polygon[i].y-polygon[i-1].y!=0&&Segment_Intersect(a,b,polygon[i],polygon[i-1]))
{
if(Direction(a,polygon[i],polygon[i-1])==0)
return 1;
sum++;
}
if(sum&1)
return 0;
return 2;
}
double DotProduct(point p0,point p1,point p2)
{
return (p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
}
double MinDistance(point p0,point p1,point p2)
{
double d=Dis(p1,p2);
double u=DotProduct(p1,p0,p2)/(d*d);
if(u<0)
return Dis(p0,p1);
else if(u>1)
return Dis(p0,p2);
else
{
point v;
v.x=p1.x+u*(p2.x-p1.x);
v.y=p1.y+u*(p2.y-p1.y);
return Dis(p0,v);
}
}
int main()
{
point center;
double bj;
int n;
while(~scanf("%d",&n),n>2)
{
scanf("%lf%lf%lf",&bj,¢er.x,¢er.y);
for(int i=0; i<n; i++)
scanf("%lf%lf",&data[i].x,&data[i].y);
if(!Graham_Scan(data,n))
{
puts("HOLE IS ILL-FORMED");
continue;
}
if(Pandingdian(center,n,data))
{
puts("PEG WILL NOT FIT");
continue;
}
int f=1;
for(int i=0; i<n; i++)
if(MinDistance(center,data[i],data[(i+1)%n])<bj)
{
f=0;
break;
}
if(f)
puts("PEG WILL FIT");
else
puts("PEG WILL NOT FIT");
}
return 0;
}