poj 2540 Hotter Colder 切割多边形

/*
poj 2540 Hotter Colder 切割多边形

用两点的中垂线切割多边形,根据冷热来判断要哪一半

然后输出面积


*/
#include <stdio.h>  
#include<math.h>  
const double eps=1e-8;  
const int N=200;  
struct point  
{  
    double x,y;  
	point(){}
	point(double a,double b):x(a),y(b){}
}dian[N];  
point jiao[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);  
}  
  
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_getfaxian(point xiang)
{
     	point a;
     	if(mo_ee(xiang.x,0))
     	{
               	a.x=1;
               	a.y=0;
               	return a;
     	}else if(mo_ee(xiang.y,0))
     	{
               	a.x=0;
               	a.y=1;
               	return a;
     	}else
     	{
               	a.x=1;
               	a.y=-1.0*xiang.x/xiang.y;
               	return a;
     	}
 
}

//求多边形面积  
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]);  
    }  
	if(ret<0) ret=-ret;
    return ret/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 main()
{
	point qian(0,0);
	point cur,mid,end;
	char order[20];
	int flag=0;
	jiao[0]=point(0,0);
	jiao[1]=point(10,0);
	jiao[2]=point(10,10);
	jiao[3]=point(0,10);
	int jiaodian=4;
	while(scanf("%lf",&cur.x)!=EOF)
	{
		scanf("%lf%s",&cur.y,order);
		getchar();
		if(order[0]=='S'||flag==1)
		{
			flag=1;
			printf("0.00
");
			continue;
		}
		mid.x=(cur.x+qian.x)/2;
		mid.y=(cur.y+qian.y)/2;
		end=mo_getfaxian(point(cur.x-qian.x,cur.y-qian.y));
		end.x=mid.x+end.x;
		end.y=mid.y+end.y;
		bool zai=mo_gg(mo_xmult(end,cur,mid),0);
		if((order[0]=='H'&&zai)||(order[0]=='C'&&(!zai)))
		{
			
		}else
		{
			point tem=end;
			end=mid;
			mid=tem;
		}
		mo_banjiao_cut(jiao,mid,end,jiaodian);  
		double area=mo_area_polygon(jiao,jiaodian);
		printf("%.2lf
",area);
		qian=cur;
	}
	return 0;
}


原文地址:https://www.cnblogs.com/riskyer/p/3249418.html