【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 }
View Code

 

posted @ 2019-09-21 21:51  小布鞋  阅读(273)  评论(0编辑  收藏  举报