我需要在凹面(非凸面)内部多边形周围生成Voronoi diagram。我在网上寻找方法,但我无法弄清楚如何做到这一点。基本上,我生成点的凸包,计算双点并在这些点之间建立边缘网络。但是,当遇到内部多边形的边缘时,它必须看起来像形状的边缘,就像凸包一样。因此,通过这样做并剪切边界处的所有边缘,我最终会得到一个Voronoi图,它与内部多边形的边界有很好的边缘,并且没有位于内部多边形两边的单元格。
让我举个例子:
这个问题是单元格穿过内部多边形边缘,单元格结构和多边形形状之间没有视觉关系。
有人知道如何解决这个问题吗?是否有一些算法已经做到这一点或接近我正在努力实现的目标?
非常感谢您提供任何意见!
答案 0 :(得分:2)
您可能能够构建一致的Delaunay三角剖分(即包含多边形边作为约束的三角剖分),然后将Voronoi图形成为对偶。符合三角测量将确保三角测量中没有边缘与约束边相交 - 所有约束边都将成为三角剖分中的边。
查看Triangle包here,作为此类方法的参考。根据我的经验,它是一个快速而强大的库,虽然它是用c
而不是java
编写的。
我不确定在这个阶段我是如何理解你的图中是如何生成点(Voronoi中心)的。如果您实际上想要在多边形域中进行网格生成,那么可能还有其他方法需要考虑,尽管Triangle包支持(符合)Delaunay细化网格生成。
编辑:看起来您也可以直接形成一般线段的Voronoi图,查看VRONI库here。解决你的评论 - 我不确定你是否总能期望有一个统一的Voronoi图表,它也符合一般的多边形边界。我希望多边形边界的形状会在边界Voronoi单元上施加最大尺寸。
希望这有帮助。
答案 1 :(得分:1)
显然,您需要根据较大多边形的约束生成Voronoi图。虽然您将其称为多边形,但我注意到您的示例图具有基于样条曲线的边。我们暂时忘记了。
您要做的是确保您开始使用包含多边形(无论是由您生成还是从其他来源生成)具有相等长度的边缘;方差因子会使这看起来更自然。我可能会有10-20%的差异。
现在您的包含多边形由大致相等长度的线段限定,您可以从中开始生成Voronoi图。对于容器上的每个边缘:
当你逐步生成每个点时,你应该开始看到算法以径向方式细分凹容器的每个凸“组成区域”。
您可能想知道列表的用途。嗯,显然,你还没有完成,你只产生了你想要的总Voronoi细分的一小部分。一旦创建了凹空间的这些“边界”单元格,就不希望生成比边界单元格更靠近边界的新单元格,只需要它们位于该区域内。通过维护边界单元源点列表,您可以确保您创建的任何其他点都在那个区域内。这有点像取一个内部的Minkowski总和来确保你有一个缓冲区。现在,您可以将此衍生凹面空间中的其余单元格随机化,直至完成。
(注意事项:你必须小心这一步。如果任何“通道”区域太窄,那么这个派生空间的边界将重叠,你将有一个非简单的多边形,你可以尽管你付出了努力,但发现自己将点放在了错误的位置。解决方案是确保边缘的最大放置距离不超过最小通道宽度的一半......或者使用其他几何方法,包括Minkowski求和作为一种可能性,确保你不会使用退化的派生多边形。很可能你会以多边形结束,即片段。)
我自己还没有应用这种方法,但是虽然肯定会有错误,但我认为总体思路会让你开始朝着正确的方向发展。
答案 2 :(得分:0)
寻找一篇名为:
的论文 Kirkpatrick,David G 撰写的“连续骨架的高效计算”,写于1979年。这是摘要:
提出了一种用于构造骨架的O(n lgn)算法 任意n线多边形图形。该算法基于 O(n lgn)算法构造广义Voronoi 图表(我们的概括用线组替换点集 被约束为仅在端点处相交的段)。一般化 Voronoi图算法采用线性时间算法 合并两个任意(标准)Voronoi图。
“线段的约束仅在端点处相交”是您描述的凹面多边形。