题意:逆时针给出N个点,求这个多边形是否有核。
思路:半平面交求多边形是否有核。模板题。
定义:
多边形核:多边形的核可以只是一个点,一条直线,但大多数情况下是一个区域(如果是一个区域则必为 )。核内的点与多边形所有顶点的连线均在多边形内部。
半平面交:对于平面,任何直线都能将平面划分成两部分,即两个半平面。半平面交既是多个半平面的交集。定义如其名。
半平面交求多边形的核。
设多边形点集为 *p,核的点集为*cp。
开始时将p的所有点放到cp内,然后枚举多边形的所有边去切割cp,cp中在边内侧的点保留,外侧的点删除,注意添加交点。
在边的内侧或外侧可以用叉乘来判断,还有注意多边形点集的顺序是逆时针还是顺时针。
将3130的代码中的1改成 YES,0 改成 NO ,大于-EPS 改成 小于 EPS 就是 3335的代码。。。。。。无耻的暗爽中
POJ 3130
#include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <algorithm> #include <string> #define LL long long #define EPS (1e-9) #define Right 1; #define Left -1; using namespace std; struct P { double x,y; } p[55],tp[2510],cp[2510]; double X_Mul(P a1,P a2,P b1,P b2) { P v1 = {a2.x-a1.x,a2.y-a1.y},v2 = {b2.x-b1.x,b2.y-b1.y}; return v1.x*v2.y - v1.y*v2.x; } P Cal_Cross_Position(P a1,P a2,P b1,P b2) { double t = fabs(X_Mul(a1,a2,a1,b1))/fabs(X_Mul(a1,a2,b2,b1)); P p = {b1.x + (b2.x-b1.x)*t,b1.y + (b2.y-b1.y)*t}; return p; } int Cut_Polygon(P a1,P a2,P *tp,int n,P *cp) { double xm1,xm2; int i ,top = 0; for(i = 0;i < n; ++i) { xm1 = X_Mul(a1,a2,a1,tp[i]),xm2 = X_Mul(a1,a2,a1,tp[i+1]); if(xm1 > -EPS && xm2 > -EPS) { cp[top++] = tp[i]; } else if(xm1 > -EPS || xm2 > -EPS) { if(xm1 > -EPS) { cp[top++] = tp[i]; } cp[top++] = Cal_Cross_Position(a1,a2,tp[i],tp[i+1]); } } cp[top] = cp[0]; return top; } void Is_Star(P *tp,P *cp,P *p,int n) { int i,j,top; for(i = 0;i <= n; ++i) { tp[i] = p[i]; } for(top = n,i = 0;i < n; ++i) { top = Cut_Polygon(p[i],p[i+1],tp,top,cp); //cout<<"top = "<<top<<endl; if(top == 0) { cout<<"0"<<endl; return ; } for(j = 0;j <= top; ++j) { tp[j] = cp[j]; } } cout<<"1"<<endl; } int main() { int i,n; while(scanf("%d",&n) && n) { for(i = 0; i < n; ++i) { scanf("%lf %lf",&p[i].x,&p[i].y); } p[n] = p[0]; Is_Star(tp,cp,p,n); } return 0; }
POJ 3335
#include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <algorithm> #include <string> #define LL long long #define EPS (1e-9) #define Right 1; #define Left -1; using namespace std; struct P { double x,y; } p[55],tp[2510],cp[2510]; double X_Mul(P a1,P a2,P b1,P b2) { P v1 = {a2.x-a1.x,a2.y-a1.y},v2 = {b2.x-b1.x,b2.y-b1.y}; return v1.x*v2.y - v1.y*v2.x; } P Cal_Cross_Position(P a1,P a2,P b1,P b2) { double t = fabs(X_Mul(a1,a2,a1,b1))/fabs(X_Mul(a1,a2,b2,b1)); P p = {b1.x + (b2.x-b1.x)*t,b1.y + (b2.y-b1.y)*t}; return p; } int Cut_Polygon(P a1,P a2,P *tp,int n,P *cp) { double xm1,xm2; int i ,top = 0; for(i = 0;i < n; ++i) { xm1 = X_Mul(a1,a2,a1,tp[i]),xm2 = X_Mul(a1,a2,a1,tp[i+1]); if(xm1 < EPS && xm2 < EPS) { cp[top++] = tp[i]; } else if(xm1 < EPS || xm2 < EPS) { if(xm1 < EPS) { cp[top++] = tp[i]; } cp[top++] = Cal_Cross_Position(a1,a2,tp[i],tp[i+1]); } } cp[top] = cp[0]; return top; } void Is_Star(P *tp,P *cp,P *p,int n) { int i,j,top; for(i = 0;i <= n; ++i) { tp[i] = p[i]; } for(top = n,i = 0;i < n; ++i) { top = Cut_Polygon(p[i],p[i+1],tp,top,cp); //cout<<"top = "<<top<<endl; if(top == 0) { cout<<"NO"<<endl; return ; } for(j = 0;j <= top; ++j) { tp[j] = cp[j]; } } cout<<"YES"<<endl; } int main() { int i,n; int T; scanf("%d",&T); while(T--) { scanf("%d",&n); for(i = 0; i < n; ++i) { scanf("%lf %lf",&p[i].x,&p[i].y); } p[n] = p[0]; Is_Star(tp,cp,p,n); } return 0; }