您的问题实际上包含三个部分,而不是两个:
- 应该使用哪些数据结构来表示网格?
- 应该使用什么算法从网格数据结构中提取边缘?
- 应该如何表示结果集中的边缘?
需要进一步提问才能找到合适的答案。
应该使用哪些数据结构来表示网格?
您需要处理哪些元素类型?
如果您只需要处理多边形(闭合循环)和简单形状(每个节点与元素中的其他节点都相连,例如四面体),则有序节点列表就足够了,因为可以从节点列表中推断出边缘。另一方面,如果您需要处理六面体、棱柱或一般的多面体等元素类型,则需要更多关于元素拓扑的信息。一个简单的边缘映射数组通常就足够了。它只是一个指向元素节点列表中的索引的数组 [][2],告诉您如何连接给定元素类型的节点。
Chris 描述的半边结构在仅限于 2D 时是一个不错的选择。在 3D 中,每个边缘可以连接任意数量的元素,而不仅仅是两个。我认为有一种名为 pinwheel 结构的半边表示的 3D 扩展。
如果您必须支持任意元素类型,我更喜欢使用更完整的数据结构来表示元素拓扑。一个常见的选项是使用边和共边。每对连接节点都有一个边结构,每个使用该边的元素都有一个共边。它类似于 pinwheel 方法,但更加明确。
应该使用什么算法从元素中提取边缘?
速度或内存有多重要?结果是否包括每个元素中的每条边缘,或者无论多少个元素使用它,只包括一次?结果中边缘的顺序是否重要?每个边缘的节点顺序是否重要?
对于任意元素类型,很难设计一个仅访问每个边缘一次的算法。为确保每条边仅出现一次,可以过滤结果,或者可以有点粗糙,对每个边缘保留一个“已访问”位,以确保不会将其两次放入结果中。
应该如何表示结果?
我将如何使用结果的方式有什么关系吗?
如果您要在计算密集型的计算中使用结果,那么一个大的坐标数组可能是最好的选择。您不希望在计算过程中反复获取节点坐标。但是,如果您正在过滤结果以删除重复的边缘,则比较坐标(对于节点对来说有6个双精度浮点数)并不是正确的方法。如果您正在过滤,请先生成指向边缘结构的指针列表,然后过滤掉重复项,然后再生成您的坐标列表。您也可以将此方法用于节点对,但是然后您必须针对每个边缘过滤两个可能的节点顺序,从而将过滤时间加倍。
如果内存比性能更重要,那么边缘指针列表也是一种好方法。但是,您不需要将边缘列表转换为坐标列表,而是在计算过程中查找坐标。这种方式获取节点坐标会比较慢,但是您避免了制作大量坐标列表 - 每个边缘只需存储一个指针而不是每个边缘存储6个双精度浮点数。
许多网格应用程序将所有坐标存储在一个大的全局数组中,每个节点都有一个索引指向该数组。如果是这种情况,那么将边缘列表转换为全局坐标数组的索引列表,而不是转换为坐标数组。性能应该与本地坐标数组差不多,但没有内存和人口过度开销。