计算几何-多边形内核判定-HPI-poj3335

This article is made by Jason-Cow.
Welcome to reprint.
But please post the article's address.

 

先解决一个问题,什么是多边形内核

形象的说就是在多边形中可以找到一个区域安放一台360°摄像头,能够监视到整个凸多边形区域

 

用手在多边形内侧摸一圈,凹凸不平?!

对,就是这个感觉。

 

借助数学必修5线性规划的思想,可以将多边形的n条边

看做n个线性约束条件

然后,在二位笛卡尔坐标系下求交集就好了(显然

证明!

 

题目:poj3335

好,是不是直接上半平面交?!

 

我想给一组数据,poj上的,反正吓得我一弹,冷静的加了一行

 

bool Left(L l,D A){return Cross(l.v,A-l.P)>0||fabs(Cross(l.v,A-l.P))<eps;}
key

 

 

 

先看数据

 

 

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <vector>
 7 #include <cmath>
 8 #include <queue>
 9 #include <map>
10 #include <set>
11 using namespace std;
12 #define sqr(x) ((x)*(x))
13 #define RG register
14 #define op operator
15 #define IL inline
16 typedef double db;
17 typedef bool bl;
18 const db pi=acos(-1.0),eps=1e-10;
19 struct D{
20   db x,y;
21   D(db x=0.0,db y=0.0):x(x),y(y){}
22 };
23 typedef D V;
24 bl operator<(D A,D B){return A.x<B.x||(A.x==B.x&&A.y<B.y);}
25 V operator+(V A,V B){return V(A.x+B.x,A.y+B.y);}
26 V operator-(V A,V B){return V(A.x-B.x,A.y-B.y);}
27 V operator*(V A,db N){return V(A.x*N,A.y*N);}
28 V operator/(V A,db N){return V(A.x/N,A.y/N);}
29 
30 db Ang(db x){return(x*180.0/pi);}
31 db Rad(db x){return(x*pi/180.0);}
32 V Rotate(V A,db a){return V(A.x*cos(a)-A.y*sin(a),A.x*sin(a)+A.y*cos(a));}
33 db Dis(D A,D B){return sqrt(sqr(A.x-B.x)+sqr(A.y-B.y));}
34 db Cross(V A,V B){return A.x*B.y-A.y*B.x;}
35 
36 db Area(D*R,int n){
37     db S=0.0;
38     for(int i=1;i<n;i++)S+=Cross(R[i]-R[1],R[i+1]-R[1]);
39     return S/2;
40 }
41 
42 db Length(D*R,int n){
43     db C=0.0;
44     for(int i=2;i<=n;i++)C+=Dis(R[i],R[i-1]);
45     return C+Dis(R[n],R[1]);
46 }
47 
48 struct L{
49   D P,v;db a;
50   L(){}
51   L(D P,V v):P(P),v(v){a=atan2(v.y,v.x);}
52   bool operator<(const L x)const{return a<x.a;}
53 };
54 
55 D Intersect(L a,L b){
56   V u=a.P-b.P;
57   return a.P+a.v*(Cross(b.v,u)/Cross(a.v,b.v));
58 }
59 
60 bool Left(L l,D A){return Cross(l.v,A-l.P)>0||fabs(Cross(l.v,A-l.P))<eps;}
61 
62 int HPI(L*l,int n,D*ans){
63   int head,tail,m=0;
64   D*P=new D[n];L*q=new L[n];
65   sort(l+1,l+n+1),q[head=tail=0]=l[1];
66   for(int i=2;i<=n;i++){
67     while(head<tail && !Left(l[i],P[tail-1]))tail--;
68     while(head<tail && !Left(l[i],P[head]))  head++;
69     q[++tail]=l[i];
70     if(fabs(Cross(q[tail].v,q[tail-1].v))<eps){
71       tail--;
72       if(Left(q[tail],l[i].P))q[tail]=l[i];
73     }
74     if(head<tail)P[tail-1]=Intersect(q[tail-1],q[tail]);
75   }
76   while(head<tail && !Left(q[head],P[tail-1]))tail--;
77   if(tail-head<=1)return 0;
78   P[tail]=Intersect(q[tail],q[head]);
79   for(int i=head;i<=tail;i++)ans[++m]=P[i];
80   return m;
81 }
82 
83 const int maxn=100+10;
84 D P[maxn];L l[maxn];
85 int main(){
86     int T,n,cnt;
87     for(scanf("%d",&T);T--;){
88         scanf("%d",&n),cnt=0;        
89         for(int i=1;i<=n;i++){
90             db a,b;scanf("%lf%lf",&a,&b);
91             P[i]=D(a,b);
92         }
93       for(int i=n;i>=2;i--)
94           l[++cnt]=L(P[i],P[i-1]-P[i]);
95       l[++cnt]=L(P[1],P[n]-P[1]);
96       printf("%s\n",HPI(l,n,P)>=3?"YES":"NO");
97     }
98   return 0;
99 }
poj3335

 

posted @ 2017-03-28 21:52  墨鳌  阅读(321)  评论(0编辑  收藏  举报