【计算几何】半平面交

有向直线的定义:

struct Line
{
    Point P;//直线上任意一点 
    Vector v;//方向向量,左边是对应的半平面 
    double ang;//极角。从x正半轴旋转到向量v所需要的角度(弧度) 
    Line() {}
    Line(Point P, Vector v):P(P),v(v) { ang=atan2(v.y,v.x); }
    bool operator < (const Line& L) const { return ang<L.ang; }//极角排序 
}; 

半平面交算法:

bool OnLeft(Line L, Point p) { return Cross(L.v,p-L.P)>0; }
//和凸包类似的算法,半平面可能“绕了一圈”所以队首可能变得无用
//如果可能出现“无界”情况,需要在外面加一个大框(4个半平面) 
int HalfplaneIntersection(Line* L, int n, Point* poly)
{
    sort(L,L+n);//极角排序 
    int first,last;
    Point *p=new Point[n];//p[i]为q[i]和q[i+1]的交点 
    Line *q=new Line[n];//双端队列 
    q[first=last=0]=L[0];//初始时只有一个平面 
    for (int i=1; i<n; i++)
    {
        while (first<last && !OnLeft(L[i],p[last-1])) last--;
        while (first<last && !OnLeft(L[i],p[first])) first++;
        q[++last]=L[i];
        if (!fcmp(Cross(q[last].v,q[last-1].v))) 
        {
            last--;
            if (OnLeft(q[last],L[i].P)) q[last]=L[i];
        }
        if (first<last) p[last-1]=GetIntersection(q[last-1],q[last]);
    }
    while (first<last && !OnLeft(q[first],p[last-1])) last--; //删除无用平面

    if (last-first<=1) return 0;//空集 
    p[last]=GetIntersection(q[last],q[first]);//计算首尾两个半平面交点 

    int m=0;//从deque复制到输出 
    for (int i=first; i<=last; i++) poly[m++]=p[i];
    return m;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值