POJ 3335 Rotating Scoreboard【半平面交_多边形内核】

 题意: 给出一个有N个顶点的多边形,问该多边形内是否存在一点满足在该点可以看到多边形内部任意一个位置。

分析: 求多边形内核。

 

#include<stdio.h>
#include<string.h>
#include<math.h>
#define eps 1e-8
#define maxn 105
struct point
{
    double x,y;
}p[maxn],q[maxn],s[maxn];
int n,size,si;
void init()
{
    int i;
    for(i=1;i<=n;i++)
        p[i]=s[i];
    p[n+1]=p[1];
    p[0]=p[n];
    size=n;
}
int sig(double x)
{
    return (x<-eps)?-1:(x>eps);
}
double ab(double x)
{  return x>0?x:-x; }
point intersect(point x,point y,double a,double b,double c)
{
    double u=ab(a*x.x+b*x.y+c);
    double v=ab(a*y.x+b*y.y+c);
    point tmp;
    tmp.x=(x.x*v+y.x*u)/(u+v);
    tmp.y=(x.y*v+y.y*u)/(u+v);
    return tmp;
}
void cut(double a,double b,double c)
{
    int i;
    si=0;
    for(i=1;i<=size;i++)
    {
        if(sig(a*p[i].x+b*p[i].y+c)>=0)
            q[++si]=p[i];
        else 
        {
            if(sig(a*p[i-1].x+b*p[i-1].y+c)>0)
                q[++si]=intersect(p[i],p[i-1],a,b,c);
            if(sig(a*p[i+1].x+b*p[i+1].y+c)>0)
                q[++si]=intersect(p[i],p[i+1],a,b,c);
        }
    }
    for(i=1;i<=si;i++) // 更新多边形内核
        p[i]=q[i];
    p[0]=p[si];
    p[si+1]=p[1];
    size=si;
}
bool solve()
{
    int i;
    double a,b,c;
    for(i=1;i<=n;i++)
    {
        a=s[i+1].y-s[i].y;
        b=s[i].x-s[i+1].x;
        c=s[i+1].x*s[i].y-s[i+1].y*s[i].x;
        cut(a,b,c);
    }
    if(size)
    return true;
    return false;
}
int main()
{
    int t,i;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
            scanf("%lf%lf",&s[i].x,&s[i].y);
        s[n+1]=s[1];
        s[0]=s[n];
        init();
        if(solve())
            printf("YES\n");
        else 
            printf("NO\n");
    }
    return 0;
}
posted @ 2012-08-16 21:56  'wind  阅读(255)  评论(0编辑  收藏  举报