半平面交O(nlogn)版

本文介绍了一个用于几何计算的C++程序实现,包括点、线段等基本几何元素的定义及操作,如点的加减运算、点积和外积等,并提供了一种处理线段交点的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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];
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值