礼品包装算法(Jarvis March) - 使用Cross Product的单次运行

时间:2015-05-16 14:03:15

标签: algorithm geometry computational-geometry convex-hull cross-product

在众所周知的“算法入门 - 第3版”一书中,用于在2D空间中找到一组点的凸壳的礼品包装算法被描述为需要:

  1. 分别用于查找凸包左右链的2次运行
  2. 相对于凸包的最后一段分选极角
  3. 为了使用Cross Product技巧来分类极角并获得正确的结果。

    然而,在我看来,只考虑凸壳的最新点就足够了。这是我的方法(假设输入中没有出现3个共线点):

    pLast = latest found point of the Convex Hull
    <p1, p2, ..., pk> = points that are not (yet) in the Convex Hull
    pNext = the next point of the Convex Hull (trying to find this)
    
    pNext = p1 
    for i=2 to k 
       if (nonLeftTurn(pLast, pNext, pi) == true)
          pNext = pi
    

    这里nonLeftTurn(p1,p2,p3)如果p3位于定向线p1-> p2的右边,则返回true:

    nonLeftTurn(p1, p2, p3):
       if ( (p2 - p1) x (p3 - p1) <= 0)
          return true
       else
          return false
    

    在我看来,这种方法是正确的。我错过了什么?你能否提供一个反例,因为我找不到一个。

    谢谢!

1 个答案:

答案 0 :(得分:0)

方法是正确的,你不需要凸包的最后一段。你需要找到最近的&#34;&#34;您可以使用pLast形成的段,这意味着您需要所有剩余的点都位于该段的左侧,这样的段显然是凸包的一部分,并且您的过程正是这样做的。你可以按如下方式想象它,你拿任意点p并用pLast加入它,然后你验证所有剩余的点位于它的左边,如果右边有任何其他点q,那么你取q而不是p,notice您不需要再次检查已经检查过p的所有点,因为pLast-&gt; p左侧的所有点也位于pLast-&gt; q的左侧,因此您继续检查q剩下的几点。之前的观察意味着当您完成所有点的检查时,所有剩余点位于pLast-> pNext的左侧,因此pNext是凸包中的一个点。

Jarvis march的目标是找到最合适的片段,这就是算法设计的方式,你找到这样最合适的片段的方式可能会有所不同,我想这本书的范围并不是那么透彻可能的实现,所以我想它只是建议这两个,因为它不是计算几何书。