#include <cmath>
#include <cstdio>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1010
#define M 90010
#define eps 1e-8
using namespace std;
int n;
struct Point
{
long double x,y;
Point(){}
Point(long double a,long double b):x(a),y(b){}
friend istream& operator >> (istream &_,Point &a)
{cin>>a.x>>a.y;return _;}
Point operator + (const Point &a)
{return Point(x+a.x,y+a.y);}
Point operator - (const Point &a)
{return Point(x-a.x,y-a.y);}
Point operator * (long double rate)
{return Point(x*rate,y*rate);}
long double operator * (const Point &a)
{return x*a.x+y*a.y;}
long double operator ^ (const Point &a)
{return x*a.y-y*a.x;}
};
struct Line
{
Point p,v;
Line(){}
Line(Point a,Point b):p(a),v(b-a){}
friend bool inside(Line &a,Point &b)
{
long double x1=min(a.p.x,(a.p+a.v).x);
long double x2=max(a.p.x,(a.p+a.v).x);
return b.x>=x1&&b.x<=x2;
}
}l[N];
int lines;
Line MakeLine(Point &a,Point &b)
{
l[++lines]=Line(a,b);
return l[lines];
}
struct Triangle
{
Point a,b,c;
Line l1,l2,l3;
Triangle(){}
Triangle(Point _a,Point _b,Point _c):a(_a),b(_b),c(_c)
{
l1=MakeLine(_a,_b);
l2=MakeLine(_b,_c);
l3=MakeLine(_c,_a);
}
}tri[N];
struct Interval
{
long double l,r;
Interval(){}
Interval(long double x,long double y):l(x),r(y){}
friend bool operator < (Interval a,Interval b)
{
if(a.l==b.l)return a.r<b.r;
return a.l<b.l;
}
}interval[N];
int intervals;
Point Get_Intersection(Line &l1,Line &l2)
{
Point u=l1.p-l2.p;
long double tmp=(l2.v^u)/(l1.v^l2.v);
return l1.p+l1.v*tmp;
}
long double X[M];
int Xs;
long double Triangle_Intersect(long double x,long double height)
{
intervals=0;
for(int i=1;i<=n;i++)
{
Point p1=tri[i].a,p2=tri[i].b,p3=tri[i].c;
if(x<min(p1.x,min(p2.x,p3.x))+eps||x+eps>max(p1.x,max(p2.x,p3.x)))continue;
Line tmp=Line(Point(x,0),Point(x,1));
Point pp1=Get_Intersection(tri[i].l1,tmp);
Point pp2=Get_Intersection(tri[i].l2,tmp);
Point pp3=Get_Intersection(tri[i].l3,tmp);
if(!inside(tri[i].l1,pp1))
{
interval[++intervals].l=min(pp2.y,pp3.y);
interval[intervals].r=max(pp2.y,pp3.y);
}else if(!inside(tri[i].l2,pp2))
{
interval[++intervals].l=min(pp1.y,pp3.y);
interval[intervals].r=max(pp1.y,pp3.y);
}else
{
interval[++intervals].l=min(pp1.y,pp2.y);
interval[intervals].r=max(pp1.y,pp2.y);
}
}
sort(interval+1,interval+intervals+1);
int j;
long double length=0;
for(int i=1;i<=intervals;i=j)
{
for(j=i+1;j<=intervals;j++)
{
if(interval[j].l<interval[i].r-eps)
interval[i].r=max(interval[i].r,interval[j].r);
else break;
}
length+=interval[i].r-interval[i].l;
}
return length*height;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
Point a,b,c;
cin>>a>>b>>c;
tri[i]=Triangle(a,b,c);
}
for(int i=1;i<=3*n;i++)
{
for(int j=i+1;j<=3*n;j++)
{
if(fabs(l[i].v^l[j].v)>eps)
X[++Xs]=Get_Intersection(l[i],l[j]).x;
}
}
sort(X+1,X+Xs+1);
long double ans=0;
for(int i=2;i<=Xs;i++)
{
if(fabs(X[i]-X[i-1])>eps)
{
long double tmpx=(X[i]+X[i-1])/2.0;
long double height=X[i]-X[i-1];
ans+=Triangle_Intersect(tmpx,height);
}
}
cout<<fixed<<setprecision(2)<<ans-eps<<endl;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
BZOJ 1845 [Cqoi2005] 三角形面积并 计算几何扫描线
原文地址:http://blog.csdn.net/wzq_qwq/article/details/48289491