半平面交O(nlogn)版

int sgn( double x )
{
    if ( fabs(x)<eps ) return 0;
    if ( x<0 ) return -1;
    if ( x>0 ) return  1;
}
struct Point
{
    double x,y;
    Point(){}
    Point( double _x , double _y )
    {
        x = _x; y = _y;
    }
    Point operator -( const Point&b )const
    {
        return Point( x-b.x , y-b.y );
    }
    Point operator +( const Point&b )const
    {
        return Point( x+b.x , y+b.y );
    }
    double operator ^( const Point&b )const
    {
        return x*b.y-y*b.x;
    }
    double operator *( const Point&b )const
    {
        return x*b.x+y*b.y;
    }
};
struct Line
{
    Point s,e; double k;
    Line(){}
    Line( Point _s , Point _e )
    {
        s = _s; e = _e;
        k =atan2( e.y-s.y , e.x-s.x );
    }
    Point operator &( const Line&b )const
    {
        Point res = s;
        double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
        res.x += (e.x-s.x)*t;
        res.y += (e.y-s.y)*t;
        return res;
    }
};
bool HPIcmp( Line a , Line b )
{
    if ( fabs(a.k-b.k)>eps ) return a.k<b.k;
    return ((a.s-b.s)^(b.e-b.s))<0;
}
Line Q[20010];
void HPI( Line line[] , int n , Point res[] , int &resn )
{
    int tot = 1;
    sort( line , line+n , HPIcmp );
    for ( int i=1 ; i<n ; i++ )
        if ( fabs(line[i].k-line[i-1].k)>eps )
            line[tot++] = line[i];
    int head = 0,tail = 1;
    Q[0] = line[0];
    Q[1] = line[1];
    resn = 0;
    for ( int i=2 ; i<tot ; i++ )
    {
        if ( fabs((Q[tail].e-Q[tail].s)^(Q[tail-1].e-Q[tail-1].s))<eps||
             fabs((Q[head].e-Q[head].s)^(Q[head+1].e-Q[head+1].s))<eps ) return;
        while ( head<tail&&(((Q[tail]&Q[tail-1])-line[i].s)^(line[i].e-line[i].s))>eps ) tail--;
        while ( head<tail&&(((Q[head]&Q[head+1])-line[i].s)^(line[i].e-line[i].s))>eps ) head++;
        Q[++tail] = line[i];
    }
    while ( head<tail&&(((Q[tail]&Q[tail-1])-Q[head].s)^(Q[head].e-Q[head].s))>eps ) tail--;
    while ( head<tail&&(((Q[head]&Q[head-1])-Q[tail].s)^(Q[tail].e-Q[tail].e))>eps ) head++;
    if  ( tail<=head+1 ) return;
    for ( int i=head ; i<tail ; i++ )
        res[resn++] = Q[i]&Q[i+1];
    if ( head<tail-1 )
        res[resn++] = Q[head]&Q[tail];
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值