计算多边形周围的Voronoi

时间:2011-08-19 12:41:01

标签: java polygon computational-geometry processing voronoi

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

让我举个例子:

enter image description here

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

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

非常感谢您提供任何意见!

3 个答案:

答案 0 :(得分:2)

您可能能够构建一致的Delaunay三角剖分(即包含多边形边作为约束的三角剖分),然后将Voronoi图形成为对偶。符合三角测量将确保三角测量中没有边缘与约束边相交 - 所有约束边都将成为三角剖分中的边。

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

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

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

希望这有帮助。

答案 1 :(得分:1)

显然,您需要根据较大多边形的约束生成Voronoi图。虽然您将其称为多边形,但我注意到您的示例图具有基于样条曲线的边。我们暂时忘记了。

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

现在您的包含多边形由大致相等长度的线段限定,您可以从中开始生成Voronoi图。对于容器上的每个边缘:

  • 确定边缘法线(从该段中心向内突出的perp线)。
  • 使用边缘法线作为放置新Voronoi节点中心的滑动标尺。距边缘本身的距离将取决于你想要的平均Voronoi单元“直径”,如果它们都被视为圆圈。在你的例子中,看起来可能是30像素(或者你的世界单位中的等价物)。同样,您应该对此应用方差因子,以便不是每个单元格中心都与其源边缘等距放置。
  • 为新放置的中心生成Voronoi单元格。
  • 将您的Voronoi单元源点存储在列表中。

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

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

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

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

答案 2 :(得分:0)

寻找一篇名为:

的论文 Kirkpatrick,David G 撰写的“连续骨架的高效计算”,写于1979年。

这是摘要:

  

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

线段的约束仅在端点处相交”是您描述的凹面多边形。