题意求给出一个多边形,问这个多边形是否是凸包,如果不是数出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; }
时间: 2024-10-30 03:13:36