poj 3335 Rotating Scoreboard - 半平面交

/*
poj 3335 Rotating Scoreboard - 半平面交

点是顺时针给出的


*/
#include <stdio.h>
#include<math.h>
const double eps=1e-8;
const int N=103;
struct point
{
    double x,y;
}dian[N];
inline bool mo_ee(double x,double y)
{
	double ret=x-y;
	if(ret<0) ret=-ret;
	if(ret<eps) return 1;
	return 0;
}
inline bool mo_gg(double x,double y)  {   return x > y + eps;} // x > y
inline bool mo_ll(double x,double y)  {   return x < y - eps;} // x < y
inline bool mo_ge(double x,double y) {   return x > y - eps;} // x >= y
inline bool mo_le(double x,double y) {   return x < y + eps;} 	// x <= y
inline double mo_xmult(point p2,point p0,point p1)//p1在p2左返回负,在右边返回正
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
//求多边形面积
double mo_area_polygon(point *dian,int n)
{
	int i;
	point yuan;
	yuan.x=yuan.y=0;
	double ret=0;
	for(i=0;i<n;++i)
	{
		ret+=mo_xmult(dian[(i+1)%n],yuan,dian[i]);
	}
	return ret;
}

point mo_intersection(point u1,point u2,point v1,point v2)
{
    point ret=u1;
    double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
		/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
    ret.x+=(u2.x-u1.x)*t;
    ret.y+=(u2.y-u1.y)*t;
    return ret;
}
/

//切割法求半平面交  
point mo_banjiao_jiao[N*2];  
point mo_banjiao_jiao_temp[N*2];  
void mo_banjiao_cut(point *ans,point qian,point hou,int &nofdian)  
{  
    int i,k;  
    for(i=k=0;i<nofdian;++i)  
    {  
        double a,b;  
        a=mo_xmult(hou,ans[i],qian);  
        b=mo_xmult(hou,ans[(i+1)%nofdian],qian);  
        if(mo_ge(a,0))//顺时针就是<=0  
        {  
            mo_banjiao_jiao_temp[k++]=ans[i];  
        }if(mo_ll(a*b,0))  
        {  
            mo_banjiao_jiao_temp[k++]=mo_intersection(qian,hou,ans[i],ans[(i+1)%nofdian]);  
        }  
    }  
    for(i=0;i<k;++i)  
    {  
        ans[i]=mo_banjiao_jiao_temp[i];  
    }  
    nofdian=k;  
}  
int mo_banjiao(point *dian,int n)
{
	int i,nofdian;
	double area=mo_area_polygon(dian,n);
	if(area<0)
	{
		point temp;
		int zhong=n/2-1;
		for(i=0;i<=zhong;++i)
		{
			temp=dian[i];
			dian[i]=dian[n-1-i];
			dian[n-1-i]=temp;
		}
	}
	nofdian=n;
	for(i=0;i<n;++i)
	{
		mo_banjiao_jiao[i]=dian[i];
	}
	for(i=0;i<n;++i)
	{
		mo_banjiao_cut(mo_banjiao_jiao,dian[i],dian[(i+1)%n],nofdian);
		 if(nofdian==0)  
        {  
            return nofdian;  
        }  
	}
	return nofdian;
}
/
int main()
{
    int t,i,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(i=0;i<n;++i)
        {
            scanf("%lf%lf",&dian[i].x,&dian[i].y);
        }
        int ret=mo_banjiao(dian,n);
        if(ret==0)
        {
            printf("NO\n");
        }else
        {
            printf("YES\n");
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值