【问题标题】:Bowyer-Watson algorithm: how to fill "holes" left by removing triangles with super triangle verticesBowyer-Watson 算法:如何通过删除具有超三角形顶点的三角形来填充留下的“洞”
【发布时间】:2016-05-03 07:03:58
【问题描述】:

我正在实现 Wikipedia 中介绍的 Bowyer-Watson 算法。在我的实现中,直到伪代码的最后一部分,一切都按我的预期工作:

for each triangle in triangulation // done inserting points, now clean up
     if triangle contains a vertex from original super-triangle
        remove triangle from triangulation

如果我按照字面意义上的伪代码进行操作,我的 Delaunay 三角剖分中可能会丢失三角形。

例如,请考虑下面的图片。我正在三角剖分的站点呈现为蓝色圆圈。三角形用黑线(不包括图像边界)渲染并连接站点或边界/超级三角形顶点。外接圆用灰色渲染,它们的中心用红色圆圈渲染。每个 Voronoi 细胞都涂有不同的颜色,以(希望)使问题更加明显。

此图显示了执行上述伪代码中列出的步骤之前的三角测量状态。请注意,超级三角形的两个顶点超出了图像的右侧和底部。

此图显示了删除任何包含超三角形顶点的三角形后的步骤,无需进一步考虑:

前三个顶点应该有一个新三角形,其外心位于绿色/棕色单元格的交汇点。问题是“之前”图像中显示的角顶点在这个外接圆内,所以算法的常规处理永远不会生成这个三角形。

如何在伪代码中表达这种边缘情况,以便检查并解决它?我想避免一些可怕的“尝试所有与超级三角形顶点共享三角形的网站组合为有效的外接圆”循环。

几年前我阅读了 Bowyer 和 Watson 的论文,如有必要,我会再次阅读它们以获得答案。我希望 (1) 其他人可能有可用的答案,并且 (2) 如果我再次遇到这个问题,我可以使用 Stack Overflow 来查找答案。


编辑

所以我找到了一个相对便宜但不完美的解决方法。我的超级三角形以编程方式确定围绕站点的边界框而不与其边相交。考虑到我计算的一些外心坐标或坐标之间的距离是无限的,这个想法是由 Java 的各种令人沮丧的问题引起的。这种谨慎导致我将我的超级三角形做得如此之小,以至于它的顶点有时会落在有效三角形的外心上。增加超级三角形的大小使问题似乎消失了。但是,凸包上的三角形可能非常钝,以至于其中一个顶点仍可能落入有效的外接圆内。

我认为这意味着我最初的问题在浮点数限制面前仍然有效。有没有一种廉价的方法可以保证 Bowyer-Watson 算法生成有效的三角剖分?

【问题讨论】:

  • 您能详细说明为什么应该有一个三角形但缺少一个蓝色站点吗?我错过了什么吗?
  • 我遇到了完全相同的问题。我很惊讶BW算法有这么大的缺陷。我看到的唯一解决方案是在最后运行convex hull algorithm,这违背了目的......
  • 您找到解决方案了吗?我也有同样的问题。
  • @Axel Convex hull 并不总是有帮助。可能有未填充的区域不仅由三角形组成,而且由更大的多边形组成,需要对其进行三角剖分。我们可能会尝试在它们上递归运行 BW,但我担心它会有永远运行的风险。
  • @Somnium 我好几个月没看过这个问题了。我能想到的唯一能保证你的超圆完美的方法是制作类似 O(N^3) 的方法,收集每个可能的圆的外心,然后构建你的超三角形以保证它包含这些点。这些结果将完全独立,因此可以并行计算它们。这会破坏 O(N^2) 的运行时间并将存储需求(至少对于这部分)增加到 O(N^3)。所以...如果您有实时限制,请尝试更大的超三角形:/

标签: algorithm delaunay


【解决方案1】:

我在实现此处描述的 Bowyer-Watson 算法时遇到了同样的问题:http://paulbourke.net/papers/triangulate/。我在互联网上找不到任何有用的东西,甚至在我的大学问过,但没有结果。过了一会儿,我想出了一个解决方案。 我开始发现要使问题消失,边界三角形的顶点理想情况下应该位于无穷大,这是不切实际的。那么,如果三角形在无穷远处有一个或两个顶点,那么三角形的外接圆是什么样子的呢?它只是穿过其他点的线。因此,测试点是否位于三角形外接圆中会更改为测试点是否位于线的左侧或右侧。

算法如下所示:

  1. 检查是否有任何三角形顶点位于无穷远处。换句话说:检查三角形是否与边界三角形共享一些顶点。

  2. 如果它共享所有三个顶点:微不足道。

  3. 如果它共享零顶点:经典方法 - 检查从点到外接中心的距离是否小于外接半径。

  4. 如果它共享一个顶点:检查点是否位于其他两个顶点定义的线的左/右。 one vertex in infinity

  5. 如果它共享两个顶点:检查点是否位于由这两个顶点定义的线的左/右,但移动到第三个点。换句话说:您只从这些共享顶点之间的线中获取斜率向量并将其移动,以使线通过第三个点。 two vertices in infinity

测试点位于线的左侧还是右侧取决于您的三角形缠绕顺序。

【讨论】:

    【解决方案2】:

    您的问题似乎有解决方案,但也可以检查三角形的外心是否在超三角形之外。您可以使用多边形点测试。也许它可以保证没有丢失的三角形。

    【讨论】:

    • -1。这并不能解决问题。如果你看我的第一张照片,你会看到算法生成的最上面的外接中心在超三角形之外。无论超三角形/顶点集组合是否会产生此错误,都会发生这种情况。
    • 我花了一段时间才明白你的问题。很抱歉我从来没有这么复杂的点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-01
    • 1970-01-01
    • 2012-07-26
    • 1970-01-01
    • 2019-01-23
    • 1970-01-01
    相关资源
    最近更新 更多