【问题标题】:Calculate Voronoi around polygon计算多边形周围的 Voronoi
【发布时间】:2011-10-30 14:33:00
【问题描述】:

我需要在多边形内部的凹面(非凸面)周围生成Voronoi diagram。我已经在网上寻找方法,但我一直无法弄清楚如何做到这一点。基本上,我生成点的凸包,计算对偶点并在这些点之间建立边缘网络。但是,当遇到内部多边形的边缘时,它必须看起来像形状的边缘,就像凸包一样。因此,通过这样做并剪裁边界处的所有边缘,我应该最终得到一个 Voronoi 图,该图在内部多边形的边界上有很好的边缘,并且内部多边形的两侧没有单元格。

让我举个例子:

这样做的问题是单元格穿过内部多边形边缘,并且单元格结构和多边形形状之间没有视觉关系。

有人知道如何解决这个问题吗?是否有一些算法已经做到这一点或接近我想要实现的目标?

非常感谢您的任何意见!

【问题讨论】:

  • +1 用于可视化

标签: java polygon computational-geometry processing voronoi


【解决方案1】:

您也许可以构建一个符合要求的 Delaunay 三角剖分(即包含多边形边作为约束的三角剖分),然后将 Voronoi 图形成为对偶。符合要求的三角剖分将确保三角剖分中的任何边都不会与约束边相交 - 所有约束边都将是三角剖分中的边。

查看 Triangle 包 here,作为此类方法的参考。根据我的经验,它是一个快速而强大的库,尽管它是用 c 而不是 java 编写的。

我不确定在这个阶段我是否理解点(Voronoi 中心)是如何在您的图表中生成的。如果您确实希望在多边形域中进行网格生成,那么可能需要考虑其他方法,尽管 Triangle 包支持(符合)Delaunay 细化网格生成。

编辑:看起来您也可以直接为一般线段形成 Voronoi 图,请查看 VRONI 库,here。解决您的评论-我不确定您是否总是可以期望拥有一个统一的 Voronoi 图,该图也符合一般的多边形边界。我希望多边形边界的形状会对边界 Voronoi 单元施加最大尺寸。

希望这会有所帮助。

【讨论】:

  • Darren,我正在使用泊松圆盘采样器 (devmag.org.za/2009/05/03/poisson-disk-sampling) 生成 Voronoi 中心,以生成大小相对相等的 voronoi 细胞。接下来,我删除了太靠近内部多边形的点以减少伪影。
  • 我认为Triangle 能够帮助我。如果我是对的,我应该生成一个三角形网格,然后使用该网格,生成对偶点并从那里构建我的 Voronoi?
  • @Alex:是的——我就是这么想的。我认为你仍然必须小心边界。在某些情况下,强制三角剖分符合一组约束边可能会局部牺牲 Delaunay 标准 - 可能导致边界三角形具有外部外接中心(Voronoi 顶点)。如果你允许足够的边界细化,我认为有可能得到一个一致的、真正的 Delaunay 三角剖分,尽管我需要更加努力地考虑这一点......
  • 唯一的问题是,生成的三角形必须具有相似的表面积(给或取因数 2),所以我不会奢侈地做很多边界细化。另一方面,内部多边形非常简单(顶点不多),这可以使它更容易吗?
【解决方案2】:

显然,您需要根据更大多边形的约束生成 Voronoi 图。尽管您将其称为多边形,但我注意到您的示例图具有基于样条的边缘。让我们暂时忘记这一点。

您要做的是确保从包含多边形(无论是由您生成还是从其他来源生成)开始时具有相当等长的边;方差因子会使这看起来更自然。我可能会选择 10-20% 的差异。

既然您的包含多边形由大约相等长度的线段界定,您就有了开始生成 Voronoi 图的基础。对于容器上的每个边缘:

  • 确定边缘法线(从该线段中心向内突出的直线)。
  • 使用边缘法线作为放置新 Voronoi 节点中心的滑动刻度。与边缘本身的距离将由您希望平均 Voronoi 单元“直径”决定,如果它们都被视为圆形。在您的示例中,它看起来可能是 30 像素(或者您的世界单位中的任何等效像素)。同样,您应该对此应用方差因子,以便并非每个单元中心都与其源边缘等距放置。
  • 为新放置的中心生成 Voronoi 单元。
  • 将您的 Voronoi 单元源点存储在列表中。

随着您逐步生成每个点,您应该开始看到该算法以径向方式细分凹形容器的每个凸“成分区域”。

您可能想知道该列表的用途。好吧,显然,您还没有完成,您只生成了您想要的全部 Voronoi 镶嵌的一小部分。一旦你创建了凹空间的这些“边界”单元,你不希望新单元生成比边界单元更靠近边界,你只希望它们在那个区域内。通过维护边界单元源点的列表,您可以确保您创建的任何其他点都在那个区域内。这有点像采用内部 Minkowski 和来确保您有一个缓冲区。现在,您可以将这个派生的凹形空间中的其余单元格随机化,直至完成。

(警告:你必须小心上一步。如果任何“通道”区域太窄,那么这个派生空间的边界将重叠,你将有一个非简单多边形,你可能尽管您很努力,但还是发现自己将点放置在错误的位置。解决方案是确保距边缘的最大放置距离永远不超过最小通道宽度的一半……或使用其他几何方法,包括 Minkowski 求和作为一种可能性,以确保您不会以退化的派生多边形结束。很有可能您将以多多边形结束,即片段。)

我自己还没有应用这种方法,但是虽然肯定会有一些错误需要解决,但我认为总体思路会让你朝着正确的方向开始。

【讨论】:

    【解决方案3】:

    寻找一篇名为:

    连续骨架的高效计算”,作者 Kirkpatrick, David G,写于 1979 年。

    这是摘要:

    提出了一种用于构建骨架的 O(n lgn) 算法 任意 n 线多边形图形。该算法基于 用于构造广义 Voronoi 的 O(n lgn) 算法 图表(我们的概括用线集替换点集 线段被限制为仅在端点相交)。广义的 Voronoi 图算法采用线性时间算法 合并两个任意(标准)Voronoi 图。

    线段集仅限于在端点相交”是您描述的凹多边形。

    【讨论】:

      猜你喜欢
      • 2018-01-17
      • 1970-01-01
      • 1970-01-01
      • 2010-09-22
      • 2011-08-11
      • 2015-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多