CGAL-2维的三角剖分数据结构(理论介绍)

三角剖分数据结构是一种用于二维和高维无边界可定向三角曲面的表示方法,尤其在CGAL库中用于2D三角剖分。这种数据结构以面和顶点为中心,隐式表示边,确保拓扑完整性。它支持各种组合操作,如边翻转、顶点插入和删除。默认实现是模板化的,允许用户自定义顶点和面基类以适应特定应用需求,同时通过重新绑定机制解决模板依赖问题。这种数据结构在图形学、几何处理和算法设计中有广泛应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.定义

三角剖分数据结构是一种设计用于处理二维三角剖分表示的数据结构。三角剖分数据结构的概念主要设计用于作为嵌入平面中的三角剖分的 CGAL 2D 三角剖分类的数据结构。然而,这个概念似乎更普遍,可以用于任何无边界的可定向三角曲面,无论三角剖分嵌入的空间维度如何。
注意
-此数据结构仅适用于无边界的可定向三角曲面,无边界会成为这个数据结构的一个弊端|
-这个数据结构适用于任意维度的二维嵌入平面

1.1一个基于面以及顶点的数据结构

CGAL 2D 三角剖分的表示基于面和顶点,边仅通过两个面之间的邻接关系隐式表示。
三角剖分数据结构可以看作是保持相互关联和邻接关系的面和顶点容器。
每个三角形面都可以访问其三个入射顶点及其三个相邻面。每个顶点都可以访问其一个入射面,并通过该面访问其入射面的圆形列表。
面的三个顶点用 0、1 和 2 进行索引。面的邻居也用 0、1、2 进行索引,这样,由 i 索引的邻居与具有相同索引的顶点相对。 参见下图,图中显示的函数 ccw(i) 和 cw(i) 分别计算 i+1 和 i-1 模 3。
每条边都有两个隐式表示:与索引为 i 的顶点相对的面 f 上的边,同时可以表示为 f 与邻居(i)邻接的边。
在这里插入图片描述
单纯复形的这种或表示形式可以扩展到任何维度。更准确地说,在维度 d 中,数据结构将明确表示单元(即最大维度的面)和顶点(即维度 0 的面)。所有维度在 1 和 d-1 之间的面都将具有隐式表示。 二维三角剖分数据结构可以表示维数为 2、1 或 0 的单纯复形。

1.2面以及顶点集

由 2D 三角剖分数据结构维护的一组面使得每条边都入射到两个面。 换句话说,这组被维护的面在拓扑上等价于一个二维三角球体。(这里实际上说明可以表示的是封闭的流行网格)
此规则扩展到在退化情况下或当三角剖分少于三个顶点时出现的低维三角剖分数据结构。一维三角剖分结构维护一组顶点和边,这些顶点和边形成一个在拓扑上等效于 1 球体的环。
零维三角剖分数据结构仅包括两个在拓扑上等效于 0 球体的相邻顶点。
注意
本小节对于此数据结构表示的各个维度的具体定义进行描述。

2.三角剖分数据结构的概念

TriangulationDataStructure_2 的可以别时为用于三角剖分的面和顶点的容器。该类还负责三角剖分的组合完整性。这意味着在执行三角剖分的组合修改时,三角剖分数据结构在三角剖分的顶点和面之间保持适当的关联和邻接关系。术语组合修改是指不涉及任何关于三角剖分的几何嵌入知识的操作。例如,在给定面或给定边中插入新顶点、抑制三阶顶点、翻转两条边都是在数据结构级别执行的组合操作的示例。
三角剖分数据结构需要提供:

  • 三角剖分的顶点和面的类型 Vertex 和 Face
  • Vertex_handle 和 Face_handle 类型是 Handle 概念的模型,通过它们可以访问顶点和面。
  • 迭代器访问三角剖分的所有顶点、边和面
  • 循环器访问与给定顶点相关的所有顶点、边和面

(根据这样的需求定义的话,半边数据结是完全可以满足这样的需求的,即可以使用半边结构来替代此数据结构)
三角剖分数据结构负责面和顶点的创建和删除(内存管理)。 它提供了给出三角剖分的面数、边数和顶点数的函数。
三角剖分数据结构提供成员函数来执行三角剖分的以下组合变换:

  • 两个邻接面片邻接边的翻转
  • 添加分割给定面的新顶点,见下图
  • 添加分割给定边的新顶点(边的分裂)
  • 添加一个新顶点,将退化 - 低维三角剖分的维度提高一维
  • 去除一个与三个面片邻接的顶点
  • 删除降低三角剖分数据结构维度的顶点
    在这里插入图片描述

3.默认的三角剖分数据结构

CGAL 提供类 Triangulation_data_structure_2<Vb,Fb> 作为默认的三角剖分数据结构。

3.1灵活性

为了提供灵活性,默认的三角剖分数据结构由两个参数模板化,分别代表顶点基类和面基类。概念 TriangulationDSVertexBase_2 和 TriangulationDSFaceBase_2 描述了对三角剖分数据结构的顶点和面类的要求。
这种设计允许用户插入三角测量数据结构他自己的顶点或面类为他的应用程序调整

3.2模板参数的循环依赖项

由于邻接和关联关系存储在顶点和面中,因此顶点和面类必须知道三角剖分数据结构提供的面和顶点上的句柄类型。因此,顶点和面类需要通过三角剖分数据结构进行模板化。 因为三角剖分数据结构本身是由顶点和面类模板化的,这导致了循环依赖。 请参见图 40.3。
在这里插入图片描述
(真的是好一个你中有我,我中有你,套娃了呗!)

3.3重新绑定机制

CGAL 提出的解决这种循环依赖的解决方案是基于类似于标准分配器类 std::allocator 中使用的机制的重新绑定机制。插入三角数据结构实例化的顶点和面类本身是用假数据结构实例化的。然后,三角测量数据结构将重新绑定这些类,将自己插入假数据结构的位置,然后使用它们派生顶点和面类。重新绑定是通过顶点和面类中的嵌套模板类 Rebind_TDS 执行的,该类将重新绑定类提供为称为“Other”的类型。
这是它的工作原理。 首先,这里是三角测量数据结构中发生的重新绑定。

template < class Vb, class Fb >
class Triangulation_data_structure
{
typedef Triangulation_data_structure<Vb,Fb> Self;
// Rebind the vertex and face base to the actual TDS (Self).
// 将顶点和面基重新绑定到实际的 TDS(Self):
typedef typename Vb::template Rebind_TDS<Self>::Other VertexBase;
typedef typename Fb::template Rebind_TDS<Self>::Other FaceBase;
// ... further internal machinery leads to the final public types:
// ...进一步的内部机制导致最终的公共类型:
public:
typedef ... Vertex;
typedef ... Face;
typedef ... Vertex_handle;
typedef ... Face_handle;
};

然后,这里是具有嵌套 Rebind_TDS 模板类的顶点类,其模板参数默认设置为伪造三角数据结构的内部类型。

template < class TDS = an internal type faking a triangulation data structure >
class Vertex_base
{
public:
template < class TDS2 >
struct Rebind_TDS {
typedef Vertex_base<TDS2> Other;
};
...
};

想象一个模拟 Face_base 类。 然后按如下方式实例化三角测量数据结构:

typedef Triangulation_data_structure< Vertex_base<>, Face_base<> > TDS;

3.4利用灵活性

利用三角测量数据结构提供的灵活性有多种可能性。

  • 首先,当用户需要在顶点和面中具有不依赖于三角数据结构定义的类型的附加信息时,可以插入预定义的类 Triangulation_vertex_base_with_info_2 和 Triangulation_face_base_with_info_2。这些类有一个模板参数 Info 由用户定义的类型实例化。 它们存储这种类型的数据成员并提供对其的访问权限。
  • 其次,用户可以从默认基类派生出自己的基类: Triangulation_ds_vertex_base_2 和 Triangulation_ds_face_base_2 是要插入单独使用的三角剖分数据结构中的默认基类。三角剖分类需要一个数据结构,其中插入了其他基类。大多数三角剖分类的默认基类 Triangulation_vertex_base_2 和 Triangulation_face_base_2 是在将三角剖分数据结构插入三角剖分类时使用的默认基类。
    当使用派生时,重新绑定机制会稍微多一些,因为需要重新绑定基类本身。 然而,用户将能够在他的类中使用对三角测量数据结构提供的类型的引用。例如
template < class Gt, class Vb = CGAL::Triangulation_vertex_base_2<Gt> >
class My_vertex_base
: public Vb
{
public :
  template < typename TDS2 >
  struct Rebind_TDS {
    typedef typename Vb::template Rebind_TDS<TDS2>::Other Vb2;
    typedef My_vertex_base<Gt,Vb2> Other;
  };
  typedef typename Vb::Triangulation_data_structure Tds;
  typedef typename Tds::Vertex_handle Vertex_handle;
  ......
};

最后,用户可以编写自己的基类。 如果单独使用三角数据结构,则对基类的要求由概念 TriangulationDSVertexBase_2 和 TriangulationDSFaceBase_2 描述。如果将三角剖分数据结构插入三角剖分类,则顶点和基类的概念取决于三角剖分类。 对基本三角剖分和 Delaunay 三角剖分有效的最基本概念是 TriangulationVertexBase_2 和 TriangulationFaceBase_2。
有关利用三角剖分数据结构灵活性的示例,请参阅关于 2D 三角剖分一章的灵活性部分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值