算法 & 数据结构——最大凸包生成

记录一个最大凸多边形生成算法:通过随机顶点,生成一个包含所有顶点的凸多边形。

多边形生成算法

通过随机顶点,生成一个连接所有顶点的多边形

算法思路:

找到出于平面坐标最下面的顶点,以这个顶点为中心,对其他顶点依据角度进行排序。排序完成后,多边形就已经生成了。

C++实现:

void PolygonHull(std::vector<POINT> & points)
{
    auto val = *std::min_element(points.begin(), points.end(), [](const POINT & p1, const POINT & p2) 
        { 
            return p1.y < p2.y || p1.x < p2.x;
        });

    std::sort(points.begin(), points.end(), [&val](const POINT & p1, const POINT & p2)
        {
            auto a1 = GetAngle(val, p1), l1 = GetLengthSqr(p1 - val);
            auto a2 = GetAngle(val, p2), l2 = GetLengthSqr(p2 - val);
            return a1 < a2 || a1 == a2 && l1 < l2;
        });
}

最大凸包生成算法

算法思路:

在多边形算法的基础上,进行以下操作:

  • 1 将集合第一个顶点 p0 和第二个顶点 p1 压栈,将 p2 指向第三个顶点
  • 2 如果集合没有遍历完,则跳到步骤3,否则跳到步骤6
  • 3 判断 p2 处于 p0p1 的左边则跳到步骤4,否则跳到步骤5
  • 4 将 p2 压栈,p0,p1,p2各前进1步,跳到步骤2
  • 5 将 p1 出栈,跳到步骤2
  • 6 算法结束

C++实现:

std::vector<POINT> ConvexHull(std::vector<POINT> & points)
{
    auto val = *std::min_element(points.begin(), points.end(), [](const POINT & p1, const POINT & p2) 
        { 
            return p1.y < p2.y || p1.x < p2.x;
        });

    std::sort(points.begin(), points.end(), [&val](const POINT & p1, const POINT & p2)
        {   
            auto a1 = GetAngle(val, p1), l1 = GetLengthSqr(p1 - val);
            auto a2 = GetAngle(val, p2), l2 = GetLengthSqr(p2 - val);
            return a1 < a2 || a1 == a2 && l1 < l2;
        });

    std::vector<POINT> set;
    auto iter = points.cbegin();
    set.push_back(*iter++);
    set.push_back(*iter++);
    while (iter != points.cend())
    {
        auto & p0 = *(set.cend() - 2),
             & p1 = *(set.cend() - 1),
             & p2 = *iter;
        if (0 > Corss(p1 - p0, p2 - p1))
            set.pop_back();
        else 
            set.push_back(*iter++);
    }
    return set;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、叉积叉积的计算是线段方法的核心。对于向来p1和p2,叉积是由点(0,0)、p1、p2和p1+p2构成的平行四边...
    tdeblog阅读 886评论 0 1
  • 9.3.3 快速排序   快速排序将原数组划分为两个子数组,第一个子数组中元素小于等于某个边界值,第二个子数组中的...
    RichardJieChen阅读 1,860评论 0 3
  • 归去来兮。 1.1 说明 本篇为《挑战程序设计竞赛(第2版)》[http://www.ituring.com.cn...
    尤汐Yogy阅读 14,441评论 0 160
  • 1.把二元查找树转变成排序的双向链表 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不...
    曲终人散Li阅读 3,357评论 0 19
  • 前言 多边形偏移 (polygon offset) 算法可能我们印象不深,不过用过 autoCAD 的同学应该有印...
    zyl06阅读 11,557评论 19 14