题意:用y=h和y=-h表示围成的房子,在房子表面有一些线段表示窗户,房子外(0,f),(0,-f)有两个灯,问灯透过窗照到的总面积
解法,sum=(灯照进去每个窗的面积总和)-用每个上面的灯透过上面的窗照进去的多边形对下面的灯照进去的多边形进行相交的面积
(简单容斥)(因为不会有三个灯的面积相互相交(ps 因为窗不会相交))
#include<iostream>
#include<math.h>
#include<algorithm>
#include<stdio.h>
using namespace std;
#define eps 1e-8
int sig(double x){return (x>eps)-(x<-eps);}
struct P
{
double x,y;
P(double a=0,double b=0):x(a),y(b){}
P operator +(const P &a)const{
return P(x+a.x,y+a.y);
}
P operator -(const P &a)const{
return P(x-a.x,y-a.y);
}
P operator *(const double a)const{
return P(x*a,y*a);
}
P operator /(const double a)const{
return P(x/a,y/a);
}
double operator *(const P &a)const{
return x*a.x+y*a.y;
}
double operator ^(const P &a)const{
return x*a.y-y*a.x;
}
int operator ==(const P &a)const{
return sig(x-a.x)==0&&sig(y-a.y)==0;
}
};
double f,h;
void cal(P *p,int id,double l,double r)
{
double x1=l*(f+h)/(f-h),x2=r*(f+h)/(f-h);
if(id==0)
{
p[0]=P(x1,-h);p[1]=P(x2,-h);p[2]=P(r,h);p[3]=P(l,h);
}
else
{
p[0]=P(l,-h);p[1]=P(r,-h);p[2]=P(x2,h);p[3]=P(x1,h);
}
}
double area(P *p,int n)
{
p[n]=p[0];
double sum=0;
for(int i=0;i<n;i++)
sum+=(p[i]^p[i+1]);
sum=fabs(sum/2);
return sum;
}
P inter(P a,P b,P c,P d)
{
P res;
double t1=(b-a)^(d-a),t2=(b-a)^(c-a);
res.x=(t1*c.x-t2*d.x)/(t1-t2);
res.y=(t1*c.y-t2*d.y)/(t1-t2);
return res;
}
int cutt(P *p,int &n,P a,P b)
{
int t=0;
p[n]=p[0];
P q[10];
for(int i=0;i<n;i++)
{
if(sig((b-a)^(p[i]-a))>=0) q[t++]=p[i];
else
{
if(sig((b-a)^(p[(i+n-1)%n]-a))>0) q[t++]=inter(a,b,p[(i+n-1)%n],p[i]);
if(sig((b-a)^(p[i+1]-a))>0) q[t++]=inter(a,b,p[i],p[i+1]);
}
}
for(int i=0;i<t;i++)
p[i]=q[i];
n=t;
return n;
}
double cut(P *p,P *q)
{
int n=4;
q[4]=q[0];
for(int i=0;i<4;i++)
{
n=cutt(p,n,q[i],q[i+1]);
}
return area(p,n);
}
double l[510],r[510];
int main()
{
int n;
while(scanf("%d%lf%lf",&n,&h,&f)!=EOF)
{
double sum=0;
P p[10],q[10];
for(int i=0;i<n;i++) scanf("%lf%lf",&l[i],&r[i]);
for(int i=0;i<n;i++)
{
cal(p,0,l[i],r[i]);
for(int k=0;k<4;k++)
cout<<p[k].x<<" "<<p[k].y<<endl;
cout<<endl;
sum+=(2*area(p,4));
for(int j=0;j<n;j++)
{
cal(p,0,l[i],r[i]);
for(int k=0;k<4;k++)
cout<<p[k].x<<" "<<p[k].y<<endl;
cout<<endl;
cal(q,1,l[j],r[j]);
double s=cut(p,q);
sum-=s;
}
}
printf("%.10lf\n",sum);
}
return 0;
}