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];

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

		{

			ans[k++]=ans[i];

		}else if(mo_ll(a*b,0))

		{

			ans[k++]=mo_intersection(qian,hou,ans[i],ans[(i+1)%nofdian]);

		}

	}

	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=1;i<n;++i)

	{

		mo_banjiao_cut(mo_banjiao_jiao,dian[i],dian[(i+1)%n],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;

}


你可能感兴趣的:(core)