题目大意:给定n个三角形,求面积并 n<=100
经典的扫描线
首先求出所有直线交点的横坐标,排序,去重
然后对于每个横坐标,两段之间夹的部分一定是一个或多个梯形
因此我们取中位线,求出中位线被所有三角形覆盖区间的区间并的长度,即可计算出这部分的面积
这些东西都能YY出来- - 主要东西都看代码吧- - 希望能看懂- - 我无力叙述了- -
之前求直线被三角形截取部分长度的方法是有BUG的- - 调了一晚上+一上午- - 死にたい- -
第二个点存在四舍五入的问题 输出时减个EPS即可
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define M 110
#define ALPHA 0
#define EPS 1e-7
using namespace std;
typedef double ld;
struct Point{
ld x,y;
Point() {}
Point(ld _,ld __):
x(_),y(__) {}
friend istream& operator >> (istream& _,Point& p)
{
scanf("%lf%lf",&p.x,&p.y);
return _;
}
Point operator + (const Point &p) const
{
return Point(x+p.x,y+p.y);
}
Point operator - (const Point &p) const
{
return Point(x-p.x,y-p.y);
}
ld operator * (const Point &p) const
{
return x*p.y-y*p.x;
}
Point operator * (const ld rate) const
{
return Point(x*rate,y*rate);
}
};
struct Line{
Point p,v;
Line() {}
Line(const Point &_,const Point &__):
p(_),v(__) {}
}lines[M*3];int ltot;
struct Triangle{
Line l1,l2,l3;
ld left_bound,right_bound;
friend istream& operator >> (istream& _,Triangle &t)
{
Point p1,p2,p3;
cin>>p1>>p2>>p3;
t.l1=lines[++ltot]=Line(p1,p2-p1);
t.l2=lines[++ltot]=Line(p2,p3-p2);
t.l3=lines[++ltot]=Line(p3,p1-p3);
t.right_bound=max(max(p1.x,p2.x),p3.x);
t.left_bound=min(min(p1.x,p2.x),p3.x);
return _;
}
}triangles[M];
struct Interval{
ld l,r;
Interval() {}
Interval(ld _,ld __):l(_),r(__)
{
if(l>r) swap(l,r);
}
bool operator < (const Interval &i) const
{
return l < i.l;
}
bool Inside(double x)
{
return l<=x && x<=r ;
}
}intervals[M];int itot;
int n,xtot;
ld ans,X[M*M*9];
Point Get_Intersection(const Line &l1,const Line &l2)
{
Point u=l1.p-l2.p;
ld temp=(l2.v*u)/(l1.v*l2.v);
return l1.p+l1.v*temp;
}
ld Get_Interception(ld x)
{
int i,j;
itot=0;
for(i=1;i<=n;i++)
{
Triangle& t=triangles[i];
if( x<t.left_bound+EPS || x>t.right_bound-EPS ) continue;
Line l=Line(Point(x,0),Point(0,1));
ld y1=Get_Intersection(l,t.l1).y;
ld y2=Get_Intersection(l,t.l2).y;
ld y3=Get_Intersection(l,t.l3).y;
Interval i1(t.l1.p.x,t.l1.p.x+t.l1.v.x);
Interval i2(t.l2.p.x,t.l2.p.x+t.l2.v.x);
Interval i3(t.l3.p.x,t.l3.p.x+t.l3.v.x);
if(!i1.Inside(x))
intervals[++itot]=Interval(y2,y3);
else if(!i2.Inside(x))
intervals[++itot]=Interval(y1,y3);
else
intervals[++itot]=Interval(y1,y2);
}
sort(intervals+1,intervals+itot+1);
ld re=0;
for(i=1;i<=itot;i++)
{
ld l=intervals[i].l,r=intervals[i].r;
for(j=i+1;j<=itot;j++)
{
if(intervals[j].l<r-EPS)
r=max(r,intervals[j].r);
else
break;
}
re+=r-l;i=j-1;
}
return re;
}
int main()
{
//freopen("triangle.in","r",stdin);
//freopen("triangle.out","w",stdout);
int i,j;
cin>>n;
for(i=1;i<=n;i++)
cin>>triangles[i];
for(i=1;i<=ltot;i++)
for(j=i+1;j<=ltot;j++)
if( fabs(lines[i].v*lines[j].v)>EPS )
X[++xtot]=Get_Intersection(lines[i],lines[j]).x;
sort(X+1,X+xtot+1);
for(i=2;i<=xtot;i++)
if(fabs(X[i]-X[i-1])>EPS)
{
static ld last_x=X[1];
ld temp=Get_Interception(X[i]/2+last_x/2);
ans+=temp*(X[i]-last_x);
last_x=X[i];
}
cout<<fixed<<setprecision(2)<<ans-EPS<<endl;
return 0;
}