【问题标题】:A Brute-Force Constrained Delaunay Triangulation?蛮力约束的德劳内三角剖分?
【发布时间】:2020-05-12 00:57:45
【问题描述】:

我需要从一组点创建一个三角形网格。该集合的点数很少,因此不需要快速或优化(我将处理最多 100 点)。网格需要是受约束的“delaunay 三角剖分”。在下图中,我展示了(在左侧)我开始的一组点(蓝点和红点)。我也知道这些点之间的联系(黑色轮廓)。网格需要看起来像右边的示例(包括形成外部和内部三角形的灰色边缘)。

我不能使用库。

我研究了许多不同的算法。它们很多,很容易混淆。我想知道是否有一个简单的算法,因此我可以使用更简单的算法来生成右侧的网格?蛮力方法很好(ps:我可以做一个德劳内三角测量)。

【问题讨论】:

    标签: computational-geometry triangulation delaunay


    【解决方案1】:

    感谢大家的回答。

    我经历了为这个问题开发解决方案的过程,所以我想分享我自己的经验,希望面临这个问题的人会发现这些见解很有用。

    所以根据我自己实现算法的经验,我得出结论:

    1. 没有快速解决这个问题的方法。认为仅仅 50 行代码就可以实现是不合理的。事实上,我编写的例程(C++)大约有 400 到 500 行(用 cmets 很难分辨)。如此紧凑但具有挑战性,我花了 2 到 3 天的时间才弄好逻辑(这可能很棘手)。

    2. 我发现 Sloan 在"A FAST ALGORITHM FOR GENERATING CONSTRAINED DELAUNAY TRIANGULATIONS" 中提出的算法非常适合手头的问题。对我来说,Delaunay 三角剖分是一个新课题,现实情况是,似乎有很多不同的算法方法,而且这项研究已经很老了。所以对于一个新人来说,真的很难知道从哪里开始。

      2.1。很难知道哪种算法是最新的、理解简单、实现起来又快又简单。

      2.2 通常,一旦您了解了原理,主要就是以最有效的方式对逻辑进行编码(这似乎是上面大多数算法/论文所面临的问题)。

      2.3 我发现 Sloan 的论文易于理解,解释得很好。如果您按照逻辑和说明进行操作,那么任何人都可以真正实现受约束的 Delaunay 三角剖分。

    总之:

    1. 我推荐 Sloan 论文,因为它解释了如何创建 Delaunay 三角剖分,然后在必要时进行约束三角剖分。

    2. 要回答我自己的问题,这个问题并没有真正的蛮力。实现这项技术只需要实现完整的逻辑,并且大多数实现必须或多或少地需要相同数量的工作

    3. 有细微差别,因为我的点集非常小,所以我并没有进行太多优化。所以我确信很多算法都比 Sloan 描述的算法要好;他们可能会提出优化的数据结构和算法,以最大限度地减少三角测量中的点插入等步骤。

    所以无论如何,斯隆工作。一张小图来说明答案并使其更具吸引力;-)

    编辑

    这是生产代码,所以我不能分享它......我可能会导致我被解雇。这个过程非常简单。您在模型中寻找线段(您的约束)和所有边之间的交集。然后,对于每个相交的边,您交换该边所属的 2 个三角形之间的对角线。如果新对角线仍然与线段相交,则将新对角线重新添加到该线段的相交边堆栈中。如果新对角线不与线段相交,则将其添加到新创建的边的堆栈中。继续处理相交边的堆栈,直到它为空。

    完成后,您需要处理新添加的边列表。对于它们中的每一个,检查是否遵守 Delaunay 三角测量标准。如果不交换这条边所属的三角形的对角线。简单...

    这只是论文...

    点集

    26.9375 10.6875
    32.75 9.96875
    31.375 4.875
    27.6562 2.0625
    23.9375 -0.75
    18.1562 -0.75
    10.875 -0.75
    6.60938 3.73438
    2.34375 8.21875
    2.34375 16.3125
    2.34375 24.6875
    6.65627 29.3125
    10.9688 33.9375
    17.8438 33.9375
    24.5 33.9375
    28.7188 29.4062
    32.9375 24.875
    32.9375 16.6562
    32.9375 16.1562
    32.9062 15.1562
    8.15625 15.1562
    8.46875 9.6875
    11.25 6.78125
    14.0312 3.875
    18.1875 3.875
    21.2812 3.875
    23.4687 5.5
    25.6562 7.125
    8.46875 19.7812
    27 19.7812
    26.625 23.9688
    24.875 26.0625
    22.1875 29.3125
    17.9062 29.3125
    14.0312 29.3125
    11.3906 26.7188
    8.75 24.125
    

    这些是 x/y/z 坐标 (z=0)

    细分:

    0 1
    1 3
    3 5
    5 7
    7 9
    9 11
    11 13
    13 15
    15 17
    17 19
    19 20
    20 22
    22 24
    24 26
    26 0
    28 29
    29 31
    31 33
    33 35
    35 28
    

    索引从 0 开始(0 -> 顶点列表中的第一个顶点)

    【讨论】:

    • :你好,你能分享一下你的代码吗?我对三角形与约束边相交的部分的 sloan 感兴趣。据说改变四边形的对角线并重复它直到它适合。最终找到新的顶点Vn和Vm!这部分我没看懂!提前致谢!
    • :你试过我的算法了吗?你能把你的例子的要点发给我吗?
    • :嘿,谢谢,我明白了:imgur.com/a/DPZUx。上是凹dt,下是dt。 IMO 由于 alphashape,凹算法有一个洞,但为什么有一个红色的内边框?好吧,结果有点令人困惑,但它是CONCAVE ALGO。您需要约束边还是只需要 sloan 的点?
    • 是的,这似乎只是 DT。但是很好;-) 是的,我指定了约束边缘需要是什么。抱歉,这不在数据集中。让我为你添加这个。它将以我给你的顶点数组中的索引的形式出现。将在本周晚些时候执行此操作。
    • @bettedev:刚刚为细分添加了数据
    【解决方案2】:

    我尝试使用 alpha 形状对一些形状 https://concavehull.codeplex.com/ 进行了很好的测试,但它与最初的约束 delaunay 三角剖分相去甚远。

    这是我的 alpha 形状算法:https://alphashape.codeplex.com

    【讨论】:

    • 非常感谢您的提示。我现在正在尝试 Sloan 算法(1992 年),如果我让它工作,我会发布我的结果。如果我不这样做,我会尝试/看看你的解决方案。
    • @user18490:我从 Sloan 那里读到了一点。 IMO 不值得,但你可以试试 Bowyer-Watson。你可以将它与希尔伯特排序一起使用。但是 sloan 并没有解决 cdt。
    • 感谢您的建议。我正在看这篇论文。 researchgate.net/profile/Scott_Sloan/publication/… CDT 有一个算法。我会看看你提到的其他技术
    • (at)Bettedev 所以 Bowyer-Watson 似乎给了我一个 DT,但我如何获得这个 CDT?通过使用您提到的希尔伯特排序?请你说得更具体一点。我将不胜感激。谢谢
    • @user18490:剪耳,但不会产生 dt。或者试试我的:)。
    【解决方案3】:

    一个简单的方法似乎是实现ear clipping 算法。没有像哈希网格或quad trees 那样的优化。对于剪耳,您只需检查每三个连续的顶点 a、b 和 c。如果 b 是凸的,并且多边形的其他顶点不位于三角形 abc 内,那么您可以剪裁此三角形,将多边形的边界减少一个顶点 b。

    此外,您还必须存储邻里关系。因此,每个三角形最多引用其三个邻居。

    完成三角剖分后,将其转换为受约束的 Delaunay 三角剖分 (CDT)。这可以通过edge flipping 完成。因此,您必须检查外接圆的每个三角形。如果相邻三角形没有顶点位于三角形内,则符合 CDT,否则翻转发生违规的三角形边缘。

    由于 cmets 中的@Betterdev 而编辑:可以通过添加桥将输入多边形中可能的孔添加到初始边界。作为预处理,可以通过“双”边将孔的顶点连接到边界的顶点。这始终是可能的,并使每个孔成为主要多边形边界的一部分;并且适用于耳夹。然而,通过这些桥梁存储邻居对于翻转至关重要。

    【讨论】:

    • :剪耳是delaunay吗?
    • @Betterdev 不,剪耳只是一种简单的三角测量算法。这就是为什么我还将翻转算法描述为第二步。然后,边缘翻转会将三角剖分转换为 CDT。
    • :洞和交叉口呢?
    • 如果输入多边形很简单,就不应该有交叉。如果您有交叉约束,可以使用扫描线或只是蛮力来计算交叉点并解决交叉点。
    • :sloan算法呢?它可以对交叉口和洞口进行三角测量吗?
    【解决方案4】:

    我之前研究过一个矢量图形包,所以我无法告诉你我盯着那个确切的“e”图形看了多少小时。我最终选择了earcut 库来对点数据进行三角测量。与 libtess-2 等库相比,它非常快速且简单得多。

    【讨论】:

      猜你喜欢
      • 2012-04-27
      • 1970-01-01
      • 2012-05-06
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 2013-11-18
      • 2014-03-24
      相关资源
      最近更新 更多