码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1845 [Cqoi2005] 三角形面积并 计算几何扫描线

时间:2015-09-08 20:14:44      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:排序   代码   x   

题意:链接

方法:扫描线

解析:

扫描线裸题。

先搞出所有边。

之后求一下所有边的交点。

按照x坐标排序。

之后每两个不同的坐标间的面积其实就是中间截出来的所有梯形以及三角形的中位线的和乘以高度。

至于中位线,再用这个与y轴平行的线截一下所有的三角形即可。

统计长度。把所有的加起来即可。


卡精!


代码:

#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] 三角形面积并 计算几何扫描线

标签:排序   代码   x   

原文地址:http://blog.csdn.net/wzq_qwq/article/details/48289491

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!