Javis March计算凸包问题

根据邓老师的讲解,实现Javis March算法计算凸包,但是时间复杂度并没有直接降低,在最坏的情况下还是O(n^2).
实际上,该算法是在极边法上的改进,降低算法寻找边的复杂度..

具体的计算过程如下描述.

#include <iostream>
#include <vector>

using namespace std;

struct point
{
    point(int _x = 0, int _y = 0) : x(_x), y(_y) {}

    int x;
    int y;
};

enum Loc
{
    left,
    online,
    right
};

struct node
{
    node(point _p) : p(_p), next(nullptr), prev(nullptr) {}

    point p;
    node *prev;
    node *next;
};

int Area(point p, point q, point s)
{
    return p.x * q.y - p.y * q.x +
           q.x * s.y - q.y * s.x +
           s.x * p.y - s.y * p.x;
}

Loc ToLeft(point p, point q, point s)
{
    auto area = Area(p, q, s);
    if (area > 0)
        return Loc::left;
    if (area == 0)
        return Loc::online;
    if (area < 0)
        return Loc::right;
}

int Ltl(vector<point> points)
{
    int ltl = 0;
    for (int i = 0; i < points.size(); ++i)
    {
        if (points[i].y < points[ltl].y || (points[i].y == points[ltl].y && points[i].x < points[ltl].x))
            ltl = i;
    }
    return ltl;
}

int main()
{
    vector<point> points = {
            {1, 1},
            {2, 2},
            {2, 0},
            {2, 4},
            {3, 3},
            {4, 2}
    };
    vector<bool> flag(points.size(), false);
    int ltl = Ltl(points);
    vector<point> res;
    int k = ltl;
    do
    {
        res.push_back(points[k]);
        int s = -1;
        for (int i = 0; i < points.size(); ++i)
        {
            if (i != k && i != s &&
                (s == -1 || ToLeft(points[k], points[s], points[i]) != Loc::left)
                    && (flag[i] == false))
                s = i;
        }
        k = s;
        flag[k] = true;
    } while (k != ltl);

    for(auto p: res)
        cout << p.x << " " << p.y << endl;
    return 0;
}

参考

1 学堂在线-计算几何

猜你喜欢

转载自blog.csdn.net/qust_waiwai/article/details/81081859