求凸包算法详解.docxVIP

  • 21
  • 0
  • 约1.09千字
  • 约 3页
  • 2023-01-17 发布于四川
  • 举报
概念 凸包(Convex Hull)是一个计算几何(图形学)中的概念。用不严谨的话来讲,给定二 维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边型,它能包含点集中全部 点的。严谨的定义和相关概念参见维基百科:凸包。 这个算法是由数学大师葛立恒(Graham)创造的,他曾经是美国数学学会(AMS)主席、 ATT首席科学家以及国际杂技师协会(IJA)主席。(太汗了,这位大牛还会玩杂技?)问题 给定平面上的二维点集,求解其凸包。 过程 .在全部点中选取y坐标最小的一点H ,当作基点。假如存在多个点的y坐标都为最 小值,则选取x坐标最小的一点。坐标相同的点应排解。然后依据其它各点p和基点构成 的向量<H,p>与x轴的夹角进行排序,夹角由大至小进行顺时针扫描,反之则进行逆时针 扫描。实现中无需求得夹角,只需依据向量的内积公式求出向量的模即可。以下图为例, 基点为H,依据夹角由小至大排序后依次为H,K,C,D,L,F,G,E,I,B,A,J。下 面进行逆时针扫描。 .线段<H, K>肯定在凸包上,接着加入C。假设线段<K, C>也在凸包上,由于就H , K , C三点而言,它们的凸包就是由此三点所组成。但是接下来加入D时会发觉,线段<K, D>才会在凸包上,所以将线段<K, C>排解,C点不行能是凸包。 .即当加入一点时,必需考虑到前面的线段是否会消失在凸包上。从基点开头,凸包 上每条相临的线段的旋转方向应当全都,并与扫描的方向相反。假如发觉新加的点使得新 线段与上线段的旋转方向发生变化,则可判定上一点必定不在凸包上。实现时可用向量叉 积进行推断,设新加入的点为Pn + 1,上一点为Pn ,再上一点为Pn -1。顺时针扫描时,假 如向量<Pn - 1, Pn>与<Pn, Pn + 1>的叉积为正(逆时针扫描推断是否为负),则将上一点删 除。删除过程需要回溯,将之前全部叉积符号相反的点都删除,然后将新点加入凸包。 J H 在上图中,加入K点时,由于线段<H,K>相对于<H,C>为顺时针旋转,所以C点不在 凸包上,应当删除,保留K点。接着加入D点,由于线段<K, D>相对<H, K>为逆时针旋 转,故D点保留。依据上述步骤进行扫描,直到点集中全部的点都遍例完成,即得到凸包。 简单度 这个算法可以直接在原数据上进行运算,因此空间简单度为0(1)。但假如将凸包的结 果存储到另一数组中,则可能在代码级别进行优化。由于在扫描凸包前要进行排序,因此 时间简单度至少为快速排序的O(nlgn)。后面的扫描过程简单度为0(n),因此整个算法的 简单度为O(nlgn)o

文档评论(0)

1亿VIP精品文档

相关文档