计算几何-经典算法-凸包

   计算几何-经典算法-凸包

       在学习了一些有关计算机几何的基础知识和一些基本工具之后要快速的解决一些简单的几何问题,

       如两点之间的距离、两线段的交点个数等等是可以轻松应付的,

      但是对于复杂点的几何问题,我们还是要有更好的算法,这样才可以更高效的解决它。

      在这一篇中来总结 平面凸包 的 Graham算法;http://www.cnblogs.com/jbelial/

      平面凸包 :

       定义:对一个简单多边形来说,如果给定其边界上或内部的任意两个点,

      连接这两个点的线段上的所有点都被包含在该多边形的边界上或内部的话,则该多边形为凸多边形 。

      在解决平面凸包下面介绍了两种算法:

      一、 Graham扫描法,运行时间为O(nlgn)

      二、  Jarvis步进法,运行时间为O(nh),h为凸包中的顶点数。

      例题 1
        1 问题描述1:
        2 求覆盖平面上n 个点的最小的凸多边形。
       也可以这样描述:给定一个连接的多边形,可能是凸多边形,也有可能是凹多边形。
       现在,你的任务就是编程求这个多边形的最小凸包。
       如果它本身是凸多边形,那么最小凸包就是它本身。
        3 数据范围:
        4 多边形顶点坐标X,Y 是非负整数,不超过512。
        5 输入:
        6 共有K 组数据,每组测试数据的点都是按逆时针顺序输入的,没有3 个点共线。
        7 每组测试数据的第1 行是N,表示有N 个点。以下N 行,每行两个整数X,Y。
        8 输出:
        9 输出格式与输入格式一样,第一行是K,表示共有K 组输出。以下K 组数据:
       10 每组的第一行为M,表示该凸包上有M 个顶点,以下M 行每行两个整数X,Y,
       表示凸包顶点的坐标。也按逆时针方向输出。
       11 样例输入:
       12 1
       13 14
       14 3030
       15 5060
       16 6020
       17 7045
       18 8639
       19 11260
       20 200113
       21 25050
       22 300200
       23 130240
       24 76150
       25 4776
       26 3640
       27 3335
       28 样例输出:
       29 1
       30 8
       31 6020
       32 25050
       33 300200
       34 130240
       35 76150
       36 4776
       37 3030

  

                                                                                                                  

      Graham扫描法

      基本思想:通过设置一个关于候选点的堆栈s来解决凸包问题。

      操作:输入集合Q中的每一个点都被压入栈一次,

      非CH(Q)(表示Q的凸包)中的顶点的点最终将被弹出堆栈,

      当算法终止时,堆栈S中仅包含CH(Q)中的顶点,

      其顺序为个各顶点在边界上出现的逆时针方向排列的顺序。

      注:下列过程要求|Q|>=3,它调用函数TOP(S)返回处于堆栈S 顶部的点,

      并调用函数NEXT-TO –TOP(S)返回处于堆栈顶部下面的那个点。

      但不改变堆栈的结构。

      GRAHAM-SCAN(Q)

      设P0 是Q 中Y 坐标最小的点,如果有多个这样的点则取最左边的点作为P0;

      设<P1,P2,……,Pm>是Q 中剩余的点,对其按逆时针方向相对P0 的极角进行排序,

      如果有数个点有相同的极角,则去掉其余的点,只留下一个与P0 距离最远的那个点;

      PUSH(p0 , S)

      4  PUSH(p1 , S)

      5PUSH(p3 , S)

      for i 3 to m

      do while 由点NEXT-TOP-TOP(S),TOP(S)和Pi 所形成的角形成一次非左转

       do POP(S)

      9 PUSH(pi , S)

      10return S

      首先,找一个凸包上的点,把这个点放到第一个点的位置P0

      然后把P1~Pm按照P0Pi的方向排序,可以用矢量积(叉积)判定。

      做好了预处理后开始对栈中的点<p3,p4,...,pm>中的每一个点进行迭代,

      在第7到8行的while循环把发现不是凸包中的顶点的点从堆栈中移去。

      (原理:沿逆时针方向通过凸包时,在每个顶点处应该向左转。

      因此,while循环每次发现在一个顶点处没有向左转时,就把该顶点从堆栈中弹出。)

      当算法向点pi推进、在已经弹出所有非左转的顶点后,就把pi压入堆栈中。

     

         举例如下:

 

        

 

   

     

     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenSAL1.1 包含了算法导论中所有数据结构和算法以及其他内容,本资源为该算法库的动态链接库 内容如下(*号表示1.1版本新增内容): 数据结构:一般堆、二项堆、斐波那契堆、红黑树、通用散列(采用全域散列和完全散列技术)、不相交集合、任意维数组、高维对称数组。 图论算法(兼容有向图,无向图):广度和深度优先遍历、确定图是否存在回路、拓扑排序、强连通分支、欧拉环(欧拉路径)、最小生成树(Kruskal、Prim)、单源最短路径(3种)、每对顶点间最短路径(2种)、最大流(2种)等等。 代数算法:霍纳法则计算多项式和、矩阵乘法(2种)、方阵的LUP分解、解线性方程组(2种)、矩阵求逆(2种)、求伪逆矩阵(2种)、解正态方程组(2种)、最小二乘估计(2种)、多元最小二乘估计*、快速傅里叶变换、快速傅里叶逆变换、多维快速傅里叶变换、多维快速傅里叶逆变换、快速向量求卷积(单变量多项式乘积)、快速张量求卷积(多变量多项式乘积)、多项式除法*、快速方幂和算法。 序列算法:最长公共子序列、KMP序列匹配*、键值分离排序。 数论算法:大数类(兼容浮点数、整数、与内置类型兼容运算)*、RSA加解密系统*、解同余方程*、孙子定理解同余方程组*、Miller_Rabin素数测试(产生大质数)*、随机数(实数、大数)*、欧几里得算法*。 计算几何算法:确定任意一对线段是否相交*、凸包*、最近点对*。 运筹学:线性规划(单纯形法)*、分配问题*、最优二度子图*、多01背包问题*

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值