zoukankan      html  css  js  c++  java
  • 凸包

    转载摘自大神博客:

    https://thewalker88.com/?p=84

    求组成凸包的点坐标,周长面积等问题

    针对这个问题:Melkman复杂度n,且可以在线处理,而Graham复杂度nlogn(因为必须先排序)
    平面上有一个简单多边形,沿着多边形的边,按照逆时针的顺序给出多边形的顶点的坐标,要求你求出此多边形的凸包。
    如果是一般散点集问题的话,那它跟Graham复杂度相同,均需要先排个序nlogn

    melkman算法想象成渔网网鱼就成,左右边同时包揽

    struct Vector
    {
    double x, y;
    };
    struct Point
    {
    double x, y;
    } p[N],dq[N];
    bool cmp(Point a, Point b)
    {
    if (a.y == b.y)
    return a.x < b.x;
    return a.y < b.y;
    }
    double Cross(Vector A, Vector B) { return A.x * B.y - A.y * B.x; }//叉乘,右手螺旋,左上正右下负
    double side(Point a, Point b, Point p)//判断p在a->b直线那一侧
    {
    Vector A = (Vector){b.x - a.x, b.y - a.y};
    Vector B = (Vector){p.x - a.x, p.y - a.y};
    return Cross(A, B);
    }
    
    void Melkman(int n, int &head, int &tail)
    {
    sort(p + 1, p + 1 + n, cmp);//如果是处理一般点集问题,这里排序保证了这只“渔网”从西南角往东北角突击
    dq[head = n] = p[2];//这里直接丢1,2进来,3并不需要如网上说的手动调
    dq[tail = n + 1] = p[1];
    dq[++tail] = p[2];
    For(i, 3, n)
    {
    // if (side(dq[head + 1], dq[head], p[i])<0 && side(dq[tail - 1], dq[tail], p[i])>0)//如果是处理简单多边形的题要加这句话
    // continue;
    while (tail - head >= 2 && side(dq[head + 1], dq[head], p[i]) >= 0)//head+1->head从左路包揽敌人,如果有更左侧的鱼,那就调整角度向左扩张渔网
    ++head;
    dq[--head] = p[i];
    while (tail - head >= 2 && side(dq[tail - 1], dq[tail], p[i]) <= 0 )//tail-1->tail从右路包揽敌人
    --tail;
    dq[++tail] = p[i];
    }
    }
    For(i,head,tail-1)//因为head和tail存的值一定相同,输出点坐标输出一边就行
    cout<<dq[i].x<<" "<<dq[i].y<<endl;
  • 相关阅读:
    软件开发项目文档模版
    Java Swing 非常漂亮的外观Nimbus使用方法
    周00王总监 宁波浦一的同仁们 有看见的进来
    冰川世界
    君住长江头,我住长江尾,日日思君不见君,共饮长江水
    可乐男孩被保送上大学
    变形金刚2
    爱无罪
    英语习惯口语简写
    看完了团长,我没有心理在去看《南京!南京!》
  • 原文地址:https://www.cnblogs.com/planche/p/9426915.html
Copyright © 2011-2022 走看看