首页 > 技术文章 > POJ 3130 How I Mathematician Wonder What You Are! /POJ 3335 Rotating Scoreboard 初涉半平面交

fuhaots2009 2013-11-19 09:49 原文

题意:逆时针给出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;
}


 

 

推荐阅读