【poj1584】【模板】【计几】判断多边形是否凸包,判断圆是否在凸包内,
题目链接:https://vjudge.net/problem/POJ-1584
询问多边形是否为凸包,是凸包的话问圆是否在凸包内,这个要先判断圆心是否在凸包内,在判断半径和圆心到边的距离(这个用等面积法,就是叉积)的关系。
三个模板一起放;
1 /************************************************************************* 2 > File Name: poj1584.cpp 3 # File Name: poj1584.cpp 4 # Author : xiaobuxie 5 # QQ : 760427180 6 # Email:760427180@qq.com 7 # Created Time: 2019年09月21日 星期六 20时28分44秒 8 ************************************************************************/ 9 10 #include<iostream> 11 #include<cstdio> 12 #include<map> 13 #include<cmath> 14 #include<cstring> 15 #include<set> 16 #include<queue> 17 #include<vector> 18 #include<algorithm> 19 using namespace std; 20 typedef long long ll; 21 #define inf 0x3f3f3f3f 22 #define pq priority_queue<int,vector<int>,greater<int> > 23 ll gcd(ll a,ll b){ 24 if(a<b) return gcd(b,a); 25 return b==0?a:gcd(b,a%b); 26 } 27 28 29 #define pi 3.141592654 30 #define eps 1e-6 31 const int N=1010; 32 int n; 33 int sgn(double x){ 34 if(fabs(x)<eps) return 0; 35 if(x<0) return -1; 36 return 1; 37 } 38 struct Point{ 39 double x,y; 40 Point operator - (const Point& b)const{ 41 return (Point){x-b.x,y-b.y}; 42 } 43 double operator * (const Point& b)const{ 44 return x*b.x+y*b.y; 45 } 46 double operator ^ (const Point& b)const{ 47 return x*b.y-b.x*y; 48 } 49 }p[N]; 50 double dist(Point a,Point b){ 51 return sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y)); 52 } 53 double angle(Point o,Point a,Point b){ 54 return acos( ((a-o)*(b-o)) / (dist(o,a)*dist(o,b)) ); 55 } 56 //判断是否凸包 57 bool is_covbag(){ 58 int dir=0; 59 for(int i=0;i<=n-1;++i){ 60 int tem=sgn( (p[i+1]-p[i]) ^ (p[i+2]-p[i+1]) ); 61 if(!dir) dir=tem; 62 if(dir*tem<0) return 0; 63 } 64 return 1; 65 } 66 //判断点是否在内 67 bool is_in(Point o,double pr){ 68 double ang=0; 69 for(int i=1;i<=n;++i){ 70 if(sgn( (o-p[i]) ^ (o-p[i+1]) )>=0) ang+=angle(o,p[i],p[i+1]); 71 else ang-=angle(o,p[i],p[i+1]); 72 } 73 if(sgn(ang)==0) return 0; //在外部 74 if(sgn(ang-2*pi)==0 || sgn(ang+2*pi)==0) return 1; //在内部 75 //在边上 76 if(sgn(pr)==0) return 1; 77 return 0; 78 } 79 //判断圆和多边形是否相交 80 bool is_right(Point o,double pr){ 81 for(int i=1;i<=n;++i){ 82 double h=fabs( (p[i]-o) ^ (p[i+1]-o) ) / dist(p[i],p[i+1]) ; 83 if(sgn(h-pr)<0) return 0; 84 } 85 return 1; 86 } 87 int main(){ 88 while(~scanf("%d",&n) && n>=3){ 89 double pr,px,py; 90 scanf("%lf %lf %lf",&pr,&px,&py); 91 for(int i=1;i<=n;++i) scanf("%lf %lf",&p[i].x,&p[i].y); 92 p[n+1]=(Point){p[1].x,p[1].y}; 93 p[0]=(Point){p[n].x,p[n].y}; 94 if(!is_covbag()){ 95 puts("HOLE IS ILL-FORMED"); 96 } 97 else{ 98 if(!is_in( (Point){px,py} , pr ) || !is_right( (Point){px,py} , pr ) ) puts("PEG WILL NOT FIT"); 99 else puts("PEG WILL FIT"); 100 } 101 } 102 return 0; 103 }