poj 2540 Hotter Colder 切割多边形

时间:2021-08-11 23:16:09
/*
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\n");
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\n",area);
qian=cur;
}
return 0;
}