计算几何-多边形内核判定-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;}
先看数据
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 }
~~Jason_liu O(∩_∩)O