【发布时间】:2011-10-05 09:38:20
【问题描述】:
我正在实现一种算法,我需要在其中操纵网格,快速添加和删除边,并以 CCW 或 CW 顺序快速迭代与顶点相邻的边。
翼边结构用于描述我正在使用的算法,但我找不到任何关于如何在此数据结构上执行这些操作的简明描述。
【问题讨论】:
标签: c data-structures graph implementation mesh
我正在实现一种算法,我需要在其中操纵网格,快速添加和删除边,并以 CCW 或 CW 顺序快速迭代与顶点相邻的边。
翼边结构用于描述我正在使用的算法,但我找不到任何关于如何在此数据结构上执行这些操作的简明描述。
【问题讨论】:
标签: c data-structures graph implementation mesh
我在大学就知道了,但那是不久前的事了。
为了回答这个问题,我也在网上搜索了任何好的文档,但没有找到好的文档,但我们可以在这里查看 CCW 和 CW 顺序和插入/删除的快速示例。 看看这个表格和图形: 从这个页面:
http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/model/winged-e.html
该表仅提供一条边 a 的条目,在真实表中,每条边都有这一行。你可以看到你得到了:
但关键点来了:它给出了它们相对于边缘的方向,在这种情况下是X->Y,并且当它被右遍历时(e->a->c)。
因此,对于遍历图形的 CW 顺序,这很容易阅读:edge a left 有右继任者 c,然后您查看边缘 c 的行。
好的,这个表对于CW-order遍历很容易阅读;对于CCW,您必须考虑“当我向后走这条边时,我来自哪个边”。实际上,通过在这种情况下采用左遍历前驱 b 并以相同的方式继续使用边 b 的行条目,您可以有效地获得 CCW 顺序的下一条边。
现在插入和删除:很明显,您不能只删除边并认为图形仍然只包含三角形;在删除过程中,您必须加入两个顶点,例如图形中的X 和Y。要做到这一点,您首先必须确保边缘a 被引用的所有地方 - 我们必须修复该引用。
那么a 可以在哪里引用呢?仅在边缘b,c,d and e(所有其他边缘太远而无法知道a)加上顶点->边缘表(但我们只考虑此示例中的边缘表)。
作为我们如何修复边缘的示例,让我们看看c。像a 一样,c 有一个左右前任和后继(所以 4 个边),其中哪一个是 a?如果不检查,我们无法知道这一点,因为c 的表条目可以在其开始节点或结束节点中包含节点Y。所以我们必须检查它是哪一个,假设我们发现c在它的Start-Node中有Y,然后我们必须检查a是否是c's正确的前任(它是什么,我们找出通过查看c's 条目并将其与a 进行比较)或者它是否是c's 对继任者。 “接班人??”你可能会问?是的,因为记住两个“左遍历”列是相对于边缘向后移动的。所以,现在我们发现a 是c's 右前任,我们可以通过插入a's 右前任来修复该引用。继续其他 3 条边,您就完成了边表。修复一个额外的 Node->Vertices 当然是微不足道的,只需查看 X 和 Y 的条目并在那里删除 a。
添加边缘基本上与其他 4 个边缘的修复相反,但有一点扭曲。让我们将要拆分的节点称为Z(它将拆分为X 和Y)。您必须注意将其拆分为正确的方向,因为您可以将d 和e 组合在一个节点中,或者将e 和c 组合在一起(例如,如果新边是水平的而不是垂直的@ 987654361@在图中)!您首先必须找出即将成为 X 的哪两条边之间以及 Y 的哪两条边之间添加了新边:您只需选择哪些边应在一个节点上,哪些在另一个节点上节点:在此示例图形中:选择您想要的b、c 以及它们之间的 2 个北边在一个节点上,然后其他边在另一个节点上,这将成为 X .然后,您通过矢量减法发现新边 a 必须在 b 和 c 之间,而不是在 c 和北方的两条边之一之间。向量减法是新的X 的期望位置减去Y 的期望位置。
【讨论】: