如何沿n个给定的对角线分割多边形?

时间:2012-02-26 18:33:12

标签: computational-geometry

假设我有一个以CCW顺序(不是DCEL)表示为顶点列表的多边形,并且我有一个给定的多边形对角线列表。如何将多边形沿所有这些对角线分割成n + 1个多边形列表?

我在一个对角线上拆分列表没有问题。问题在于快速确定我的其他对角线所属的两个多边形中的哪一个。从那里,我可以将对角线列表分成两个列表,并递归地对两个分割多边形进行操作。

优选地,我想在O(n log(n))时间内执行此操作,而不是简单地绕两个分裂多项式走动以确定哪个对角线位于哪个子多边形中的明显算法。

1 个答案:

答案 0 :(得分:0)

以下是我认为解决方案的概要。

  1. 假设您已经确定对角线彼此不相交并且完全包含在多边形内。

  2. 然后(声明1)您可以认为任务是完全组合的,忘记了多边形和对角线的真实几何布局细节。让我们考虑一下这个任务,因为你给了一个带有顶点[0,1,..,N-1]的正多边形,你用一组对角线[i_k,j_k],0< = k

    <切割它/ LI>
  3. 对于任何顶点我和j让我们调用 arc_length(i, j) := min(max(i,j) - min(i,j), N - max(i,j) + min(i,j)) - 沿着循环[0,1,..,N-1]从i到j或从j到i的最小步数。

  4. 让我们调用sortedDiagonals一个容器(vector&gt;,list&gt;或类似的),在你的所有对角线中按arc_length(i,j)排序,就像

    struct LessPredicate {
      bool operator(pair<int,int> diag1, pair<int,int> diag2) const {
         return arc_length(diag1) < arc_length(diag2);
      }
    };
    
  5. 现在让我们沿着从“最短”到“最长”的sortedDiagonals的对角线切割正多边形。想象一下,一张普通的N-gon的图片刻在一个圆圈中,其中有几个第一对角线来自sortedDiagonals。显然我们在图片上看到我们的正多边形分成更小的多边形,其中一个包含圆的中心(对角线穿过中心的情况可能只发生一次,而在最后一步由于排序,所以很容易把它作为一个特例来分类)。 (陈述2)每次我们从sortedDiagonals绘制下一个对角线时,对角线属于包含中心的多边形。

  6. 现在,每次从sortedDiagonals获取下一个对角线时,您都知道包含中心的多边形(例如,您记住多边形的索引或指向其结构的指针等),因此您知道对角线所属的多边形。你用对角线将多边形切成两部分,并记住它们中的哪一个包含中心,以便在下一步中知道它。

    如果你需要证明陈述1和2,这里是草图。

    声明1是正确的,因为如果对角线完全位于给定的多边形内并且只能在它们的端点彼此相交,则此多边形具有所有这些对角线和具有相同数量的顶点和对角线的正多边形连接具有相同索引的顶点因为在给定的多边形中它们的入射数据是相同的意义上的图形相同。因此,我们将任务简化为正多边形的情况,我们需要简化对我们所知道的包含下一个对角线的多边形的说明。

    声明2.假设我们剪切了一个正方形多边形,其中someDiagonal没有穿过中心。结果是两个多边形,其中一个不包含中心 - 让我们称之为'小多边形'。对于“小多边形”中完全包含的任何diag,我们能说什么关于arc_length(diag)?它不能大于arc_length(someDiagonal)和唯一的情况

     arc_length(diag) == arc_length(someDiagonal)
    

    是diag == someDiagonal。

    现在假设我们在sortedDiagonals中绘制了常规多边形k的第一个对角线。它们中的每一个都从整个正多边形中切割出它自己的“小多边形”(可能这些'小多边形'中的一些包含来自其他对角线的其他'小多边形',没关系)。现在我们从sortedDiagonals中绘制第k-1个对角线,并注意到由于我们的排序,所有先前绘制的对角线d_i都不大于arc_length意义上的d_(k + 1)。因此,它们的“小多边形”没有arc_length的内部对角线大于或等于arc_length(d_(k + 1))。因此,d_(k + 1)不能属于sortedDiagonals中前面对角线的任何“小多边形”,它只能属于包含中心点的多边形。

    HTH