关闭

二维凸包算法

标签: 算法
522人阅读 评论(0) 收藏 举报
分类:

博客参考:http://blog.csdn.net/chao_xun/article/details/8042403
谢谢 【chao_xun】把凸包写的这么详细。

原始思路

关于凸包的问题的解决的最初思路是这样的。
<1>找到一个基准点<必须在凸边上>
<2>以基准点做射线,然后将该射线向固定方向旋转,直到接触到一个新的点。
<3>以<2>中找到的点作为新的基准点,作射线继续朝着一开始的固定的方向旋转
<4>反复重复2,3直到最后所有边闭合起来
如下图:
这里写图片描述

**

算法步骤

**
下文是参照了【chao_xun】博客中的算法的理解写出的步骤
1.首先选取一个极点,最下边的点,若最低高度相等取最左边(只要保证此点必为凸边上的点即可),以此作为基准点;
2.易知,该点一定在凸包的边上,所以可以以该点与另外一个点连线成边,作为凸包的边:以基准点为射线的端点,做一条X轴正方向的水平射线,扫面各个点与基准点所构成的向量与x轴正方向所构成的夹角,依照夹角进行排序,然后进行第三步的连边(排序的作用意义非常),下图是扫描排序的结果
这里写图片描述

3.接下来开始连边了
为了方便,以下图作为辅助
这里写图片描述
图片说明部分:
1. 经过第二步的扫描之后得到点的排列顺序为 A,B,C,D,E,F,其中A为基准点,数字分别表示两点连接成的边。
2. 规定按照逆时针方向为固定旋转方向,各点的连接顺序按照排序的结果,所以连接{A,B}就有了边【1】,可知边【1】是由前一段射线逆时针旋转过去。
3. 然后按照排序后的结果,尝试连接{B,C},可知 【2】也是以B为端点,方向与1相同的射线逆时针旋转,方向仍然是逆时针,此时也没有问题。
4. 然后按照排序的结果,连接{C,D},这时发现是顺时针旋转了,问题就来了,与我们规定的方向不相同,于是撤销边【2】和边【3】,直接连接{B,D}形成边【4】。

也就是说:假设 三个点 p2 , p3 , p4 ,数字代表他们在连边过程中加入的顺序,那么向量 p3p4一定是由向量p2p3由固定方向(逆时针)旋转过去的,如果不是,则需要将P3删除,直接连点p2和点p4,文字略为啰嗦,具体参照上图说明
最终反复循环可以连成凸包。

算法理解

关于整个算法,上面都只是步骤,个人的理解是这样的,排序后的各点的按顺序连接,最后头尾相连,其实就是结果,但是这个结果是粗糙的,为了使之成为真正的结果–凸包(也就是包含各个点,但是边长最短的图形),由三角形两边之和大于第三边,我们可以通过旋转判断从而去掉使图形凹陷的点,得到最终结果。
这里写图片描述

  • 必备知识

关于判断两个向量之间的旋转是逆时针还是顺时针,可以把二维向量扩充成三维,然后进行叉乘运算进而判断
如两个向量a=(xa,ya,0), b=(xb,yb,0)
由叉乘的运算得到 a x b=0 * i+0 * j+k(xa * yb - xb * ya);
所以只需要判断(xa * yb - xb * ya)的正负就可以确定旋转方向;

  • 推荐题目

    HDU 1392,1348

最后,个人水平是在有限,理解难免有错漏之处,希望大家指正。

0
0
查看评论

二维凸包模板 【Graham扫描算法】

推荐链接:讲的很好 模板: #include #include #include #include #define eps 1e-8 using namespace std; struct Point { double x, y; Point(){} Poin...
  • chenzhenyu123456
  • chenzhenyu123456
  • 2015-12-23 11:49
  • 684

求二维凸包算法详解

概念 凸包(Convex Hull)是一个计算几何(图形学)中的概念。用不严谨的话来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边型,它能包含点集中所有点的。严谨的定义和相关概念参见维基百科:凸包。 这个算法是由数学大师葛立恒(Graham)发明的,他曾经是美国数学学会(AM...
  • chao_xun
  • chao_xun
  • 2012-10-06 00:34
  • 2397

计算几何 二维凸包问题 Andrew算法

凸包:把给定点包围在内部的、面积最小的凸多边形。 本文介绍求解二维凸包的O(nlogn)的Andrew算法和少量例题,以及代码模板。
  • Lytning
  • Lytning
  • 2014-05-07 19:06
  • 2169

Graham Scan凸包算法

原文链接:https://segmentfault.com/a/1190000000488339;作者: Michael_Lin 获得凸包的算法可以算是计算几何中最基础的算法之一了。寻找凸包的算法有很多种,Graham Scan算法是一种十分简单高效的二维凸包算法,能够在O(nlogn)的时间...
  • dgghjnjk
  • dgghjnjk
  • 2016-06-07 11:10
  • 2012

计算几何之二维凸包:卷包裹算法、Graham Scan Algorithm、旋转卡壳算法

转自:http://www.cnblogs.com/Booble/ ==================================================================== 一.凸集&凸包 (下文中所有的集合 若不作特殊说明 都是指欧氏空间上的集合) 凸集(...
  • Strokess
  • Strokess
  • 2016-08-24 14:27
  • 2303

计算几何之求取二维点集的凸包/ 凸多边形包围盒

Graham 扫描法 1. 在点集Q中 寻找一个凸点p0;  寻找y 值最小的一个点,如果有多个y 值最小的点,则取x 值最小的; 2. 得到Q 中除p0 外的剩余点集{ p1, p2, ...pm} , 且将 剩余点集绕p0 极角排序; 如果极角相同的点有多个,则取离p0 距离最远的点,...
  • z444_579
  • z444_579
  • 2016-10-23 17:26
  • 865

解凸包问题5种算法

转载原文:http://blog.csdn.net/bone_ace/article/details/46239187 前言: 首先,什么是凸包?  定义:对于平面上的一个点集合(有限或无限),如果以集合中任意两点P和Q为端点的线段都属于该集合,我们说这个集合是凸的!可以直接说任意两点直...
  • Touch_Dream
  • Touch_Dream
  • 2016-10-05 16:40
  • 1962

凸包算法(二)--凸包面积

<br /> 凸包面积算法<br />1.选取p0作为y坐标最小的点,如果y坐标相等,选取x坐标最小的点<br />2.对剩余的点相对与p0点的极角进行排序<br />(比较叉积<http://blog.csdn.net/liufei_...
  • liufei_learning
  • liufei_learning
  • 2010-10-20 23:44
  • 5888

算法细节系列(18):凸包的三种计算

算法细节系列(18):凸包的三种计算 详细代码可以fork下Github上leetcode项目,不定期更新。 题目摘自leetcode: 1. Leetcode 587. Erect the Fence刷一道周赛题时遇到了相关的凸包计算,特此整理下,方便日后复查。不得不吐槽下,网上有很多关于凸...
  • u014688145
  • u014688145
  • 2017-05-15 20:34
  • 1461

CGAL 4.10.1 官方文档 软件包概述 ——凸包算法类

不同于OpenCV这样普及良好的大众库,CGAL并没有中文的书籍可以参考。于是萌生了翻译官方文档的想法,希望能与大家分享成果。本篇给出了CGAL官方文档凸包算法类软件包概述的译文。
  • lotusiki
  • lotusiki
  • 2017-09-18 11:36
  • 311
    个人资料
    • 访问:26897次
    • 积分:942
    • 等级:
    • 排名:千里之外
    • 原创:63篇
    • 转载:26篇
    • 译文:0篇
    • 评论:9条
    visitors
    最新评论