CGAL 二维剖分
目录
- 一、 2D Triangulations
- 1、定义
- 2 Representation
- 2.1 The Set of Faces
- 2.2 A Representation Based on Faces and Vertices
- 3 Software Design
- 4 Basic Triangulations
- 4.1 Description
- 遍历三角网顶点
- 4.2 Implementation
- 4.3 Geometric Traits
- 4.4 Example of a Basic Triangulation
- 4.5 Draw a 2D Triangulation
- 5 Delaunay Triangulations
- 5.1 Description
- 5.2 Geometric Traits
- 5.3 Implementation
- 5.4 Example: a Delaunay Terrain
- 5.5 Example: Voronoi Diagram
- 5.6 Example: Print Voronoi Diagram Edges Restricted to a Rectangle
- 6 Regular Triangulations
- 6.1 Description
一、 2D Triangulations
本章描述了CGAL的二维三角剖分。章节定义回顾了三角剖分的主要定义。Section Representation讨论了二维三角剖分在CGAL中的表示方式。软件设计部分介绍了二维三角测量软件包的总体软件设计。下一节介绍CGAL中可用的不同二维三角剖分类:基本三角剖分(基础三角剖分部分)、德劳内三角剖分(德劳内三角剖分部分)、常规三角剖分(常规三角剖分部分)、和
1、定义
二维三角剖分可以大致描述为一组平面三角形TTT ,使得:
- 两个三角面片,要么不相连,要么共享一个较低维度的面(边或顶点);
- 集合TTT中的面片相连,构成邻接关系;
- 定义域UTU_TUT是TTT中面片的并集,没有奇点。
更精确地说,三角网可以描述为单纯形的复合体。让我们首先记录一些定义。
单纯复形:是一个由单纯形组成的集合
- 集合TTT中任何面片都是TTT中的单纯形;
- TTT中的两个单纯形要么不相交,要么共用一个子面。
纬度:单纯复形的维度ddd是指单纯形的最大维数。
单纯:如果集合TTT的任何单纯形包含在具有最大维数的TTT的单纯形中,则单纯复形TTT是单纯的。
相邻:如果TTT中的两个最大维ddd的单形子共享d−1d-1d−1维子面,则称它们相邻。如果邻接关系定义了一个连通图,该连通图位于TTT的最大维数的简形集上,则称为连通的简形复数。
定义域:TTT中所有简式的并集UTU_TUT称为TTT的定义域。
奇异点:在TTT定域内的点ppp,如果它在UTU_TUT中的周围既不是拓扑球也不是拓扑盘,则称它为奇异点。
二维三角剖分可以描述为一个单纯的、连通的、无奇点的二维单纯复合体。
三角剖分的每一个面都可以给定一个朝向,而该朝向又可以引出与该面相关联的边缘的朝向。如果两个相邻的面在它们的共同入射边上诱导出相反的方向,则它们的方向称为一致的。如果每个面的方向都可以选择,使所有入射面对都具有一致的方向,那么三角剖分就被称为可定向的。
CGAL三角剖分的数据结构允许用户表示任何可定向的无边界二维三角剖分的组合。在此数据结构之上,二维三角剖分类负责三角剖分的几何嵌入,并被设计用于处理平面三角剖分。三角剖分的平面可以嵌入在更高维度的空间中。
CGAL的三角剖分是完全三角剖分,这意味着它们的定域是它们顶点的凸包。因为任何平面三角网都可以完成,这不是一个真正的限制。例如,一个多边形区域的三角剖分可以被构造并表示为一个约束三角剖分的子集,其中区域边界边已被输入为约束边(参见Section约束三角剖分、约束Delaunay三角剖分和约束与子约束之间双向映射的约束三角剖分)。
严格地说,面这个术语应该用来设计任何维度的面,三角剖分的二维面应该被恰当地称为facet。然而,按照一种常见的用法,我们以后经常称面为二维三角剖分的面。
2 Representation
2.1 The Set of Faces
CGAL的二维三角剖分可以看作是一个平面剖分,其有界面为三角形并覆盖了顶点集的凸包。这个分区的单个无界面是凸包的补面。在许多应用中,如Kirkpatrick的层次结构或增量Delaunay结构,只处理三角形面很方便。因此,一个称为无限顶点的虚构顶点被添加到三角剖分中,同时还添加了无限条边*和与之相连的无限面。每条无限边都与无限顶点和凸包的一个顶点相关联。每个无限面都与无限顶点和凸包边相关联。因此,三角剖分的每条边恰好对应两个面,三角剖分的面集在拓扑上等价于一个二维球体。注意,无限顶点没有显著坐标,也不能对它或无限面应用几何谓词。
这扩展到在退化情况下产生的低维三角剖分,或当三角剖分少于三个顶点时。包括无限面的一维三角剖分是一个由边和顶点组成的环,在拓扑上相当于一个11 - 1球体。零维三角剖分,其域简化为一个点,用两个顶点表示,在拓扑上等价于一个0- 0球。图39.2说明了这一点,示例Triangulation_2/low_dimension .cpp
显示了如何遍历低维三角剖分。
2.2 A Representation Based on Faces and Vertices
因为三角剖分是一组具有恒定尺寸复杂度的三角形面,所以三角剖分不是作为平面地图上的一层来实现的。CGAL使用了基于面和顶点而不是边缘的三角剖分的适当内部表示。这样的表示可以节省存储空间,并产生更快的算法[1]。表示的基本元素是顶点和面。每个三角形面都可以访问它的三个事件顶点和它的三个相邻面。每个顶点都可以访问它的一个入射面,并通过该面访问它的入射面的圆形列表。一个面的三个顶点按逆时针顺序用0、1和2索引。一个面的邻居也用0,1,2索引,以这样一种方式,用i索引的邻居与具有相同索引的顶点相反。如图39.3所示,图中显示的函数ccw(i)和cw(i)分别计算 i+1和 i-1对3的模。边不是显式表示的,它们只是通过两个面的邻接关系隐式表示的。每条边都有两种隐式表示:与顶点索引i相对的面f的边可以表示为f的邻居(i)的边。
3 Software Design
CGAL的三角网类提供了高级的几何功能,例如三角网中,点的位置、插入、移除或位移点。它们作为一层构建在称为三角测量数据结构的数据结构之上。三角测量数据结构可以被认为是三角测量的面和顶点的容器。此数据结构还负责三角剖分的所有组合方面。
这种几何方面和组合部分之间的分离反映在软件设计中,因为三角测量类有两个模板参数:
- 第一个参数代表一个几何特征类,它提供三角剖分的几何原语(点、段和三角形)以及这些对象上的基本操作(谓词或构造)。
- 第二个参数表示三角测量数据结构类。三角测量数据结构的概念在第2章三角测量数据结构的概念小节中有介绍。三角测量数据结构定义了用于表示三角测量的面和顶点的类型,以及用于访问和访问面和顶点的其他类型(句柄、迭代器和循环器)。
CGAL提供类Triangulation_data_structure_2<Vb,Fb>
作为三角测量数据结构的默认模型。类Triangulation_data_structure_2<Vb,Fb>
有两个模板参数,分别代表一个顶点类和一个面类。CGAL为这些模板参数定义概念,并为这些概念提供默认模型。顶点类和基类由几何特征类模板化,这使它们能够获得三角剖分的几何原语的一些知识这些默认的顶点和面基类可以被用户定制的基类替换,例如,为了处理附加到三角剖分的顶点或面的附加属性。
图39.4总结了三角测量包的设计,显示了构成该设计的三层(基类、三角测量数据结构和三角测量)。
顶层三角剖分层负责三角剖分的几何嵌入,根据不同类型的三角剖分有不同的风格:基本三角剖分、Delaunay三角剖分、规则三角剖分、约束三角剖分或约束Delaunay三角剖分。每一种三角测量对应于不同的类。图39.5总结了CGAL 2D三角测量类的派生依赖关系。任何二维三角测量类都由几何特征类和三角测量数据结构参数化。虽然一个独特的概念TriangulationDataStructure_2
描述了任何三角测量类的三角测量数据结构需求,但对几何特征类的需求实际上依赖于三角测量类。通常,顶点和面基类的需求由TriangulationVertexBase_2
和TriangulationFaceBase_2
这两个基本概念描述。然而,一些三角测量类要求基类实现对基本概念的改进。
4 Basic Triangulations
4.1 Description
类Triangulation_2<Traits,Tds>
作为其他2D三角剖分类的基类,并实现了三角剖分的用户界面。三角剖分的顶点和面通过handles
, iterators
和 circulators
访问。handles
是概念句柄的模型,它提供了两个解引用操作符*
和->
。circulator
是一种专门用于访问循环序列的类型。每当被访问的元素不是序列的一部分时,就使用句柄。迭代器和循环器用于访问三角剖分的全部或部分。
迭代器和循环器都是双向且不可变的。循环器和迭代器可转换为具有相同值类型的句柄,因此在调用成员函数时,任何句柄类型参数都可以被具有相同值类型的迭代器或循环器替换。
三角剖分类提供了一个函数,以顺时针或逆时针顺序访问一个面的顶点和邻居。有循环器访问与给定顶点或与其相邻的顶点相关的边或面。另一种循环器类型允许访问给定直线所遍历的所有面。
三角剖分类提供了一些迭代器来访问所有的面、边或顶点,也提供了一些迭代器来选择性地访问有限的面、边或顶点。
三角剖分类提供了测试任何特征的无限特性的方法,以及测试给定顶点的特定特征(边或面)在三角剖分中的存在性的方法。
三角剖分类提供了一种针对三角剖分定位给定点的方法。特别地,该方法报告点是否与三角剖分的顶点重合,是否位于边缘上,是否在面内或凸壳外。在低维三角剖分的情况下,查询点也可以位于三角剖分仿射外壳之外。
三角剖分类还提供了相对于三角剖分的给定有限面或相对于其周圆定位点的方法。三角网的面及其圆周都是逆时针方向的。
三角剖分可以通过几个函数进行修改:插入点、移除顶点、位移顶点、翻转边缘。当两个入射面的结合形成一个凸四边形时,边的翻转是可能的(见图39.6)。
三角剖分定义了Triangulation_3::All_vertices_iterator
等迭代器类型。它们的行为类似于句柄,因为不需要解引用迭代器来获得句柄。只要API需要句柄,迭代器也可以被传递。为了编写c++ 11 for循环,三角测量调用还提供了范围类型Triangulation_2::All_vertex_handles
,它有一个嵌套类型Triangulation_2::All_vertex_handles::iterator
。这个迭代器的值类型是Triangulation_2::Vertex_handle
。对于顶点和单元格的各种迭代器也是类似的。
对于范围Triangulation_2::All_edges
,它包含Triangulation_2::All_edges::iterator == Triangulation_2::All_edges_iterator
。对于用于边和点的各种迭代器也是类似的。
注意,如果您希望将pre c++ 11的for-loops与range类结合使用,则只需要迭代器类型。
遍历三角网顶点
#include <vector>
#include <iostream>
#include <CGAL/Triangulation_2.h> // 三角网
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_2<K> Triangulation;
typedef Triangulation::Vertex_handle Vertex_handle;
typedef Triangulation::Point Point;
typedef Triangulation::Finite_vertex_handles Finite_vertex_handles;// The following types are different
// Its value type is Triangulation_2::Vertex
typedef Triangulation::Finite_vertices_iterator Finite_vertices_iterator;
// Its value type is Triangulation_2::Vertex_handle
typedef Finite_vertex_handles::iterator Finite_vertex_handles_iterator;int main()
{std::vector<Point> points = { Point(0,0), Point(1,0), Point(0,1) };Triangulation T;T.insert(points.begin(), points.end());// 遍历三角网的顶点// 方法一std::cout << "Triangulation_2::Finite_vertices_iterator is like a Triangulation_2::Vertex_handle\n";for (Finite_vertices_iterator it = T.finite_vertices_begin();it != T.finite_vertices_end();++it) {std::cout << it->point() << std::endl;}// 方法二std::cout << "Triangulation_2::Finite_vertex_handles::iterator dereferences to Triangulation_2::Vertex_handle\n";Finite_vertex_handles::iterator b, e;std::tie(b, e) = T.finite_vertex_handles();for (; b != e; ++b) {// you must dereference the iterator to get a handleVertex_handle vh = *b; std::cout << vh->point() << std::endl;}// 方法三std::cout << "and you can use a C++11 for loop\n";for (Vertex_handle vh : T.finite_vertex_handles()) {std::cout << vh->point() << std::endl;}return 0;
}
4.2 Implementation
定位由一个随机游走实现。行走始于作为可选参数给出的面的顶点,或在没有可选参数给出的三角剖分的任意顶点。Delaunay三角剖分在最坏情况下需要时间O(n)O(n)O(n) ,但如果顶点均匀随机分布,平均只需O(n)O(\sqrt{n})O(n)。类Triangulation_hierarchy_2<Traits,Tds>
,在triangulationhierarchy
部分中描述,实现了一个数据结构,旨在提供一个可选的更有效的点定位算法。
点的插入是通过定位包含该点的面,并将该面分割为三个新面来完成的。如果该点落在凸包外,则通过翻转恢复三角剖分。除了位置之外,插入需要时间O(1)O(1)O(1)。这个界只是位于凸包外的点的平摊界。移除一个顶点是通过移除所有的相邻三角形,并重新三角化孔来完成的。移除所花费的时间最多与d2d^2d2成正比,其中ddd是被移除顶点的度数,对于随机顶点,该度数为O(1)O(1)O(1)。对顶点进行位移的方法是首先验证位移后三角网嵌入是否保持平面;如果是,顶点将直接放置在新位置;否则,将在新位置插入一个点,并删除原始位置上的顶点。
有限特征上的面、边和顶点迭代器是由访问所有(有限和无限)特征的对应迭代器派生的,这些特征本身是由三角剖分数据结构的相应迭代器派生的。
4.3 Geometric Traits
三角剖分的几何特征类需要提供几何对象(点、段和三角形)以及这些对象上的几何谓词来构建三角剖分。所需的谓词是:
- 两点x或y坐标的比较。
- 计算三个给定点的顺序类型的定向测试。
概念TriangulationTraits_2
描述了三角剖分的几何特征类的要求。CGAL内核类是这个概念的模型。CGAL库还使用内核几何对象和谓词提供了专门的TriangulationTraits_2
模型。这些类本身是用CGAL内核模板化的,并从内核中提取所需的类型和谓词。Projection_traits_xy_3<R>
类是一个几何特征类,用于构建地形的三角剖分。这种三角剖分是嵌入在三维空间中的二维三角剖分,数据点是三维点。三角剖分是根据这些点在xyxyxy平面上的投影建立的,然后提升到原始的三维数据点。这对于处理GIS地形尤其有用。traits类并没有真正地投影三维点,并维护每个点及其投影之间的映射(这需要占用空间并且容易出错),而是提供了忽略点的zzz坐标的几何谓词。参见Delaunay三角测量部分的示例。CGAL还提供几何性状类Projection_traits_yz_3<R>
和Projection_traits_xz_3<R>
,分别处理yzyzyz平面和xzxzxz平面上的投影,以及几何性状类Projection_traits_3<R>
处理由其正交向量定义的任意平面上的投影。
4.4 Example of a Basic Triangulation
下面的程序使用默认内核Exact_predicate_inexact_constructions_kernel
作为几何特征类和默认的三角测量数据结构创建二维点的三角测量。输入点从文件中读取并插入到三角测量中。最后将凸包上的点写入cout。
#include <fstream>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Triangulation_2.h>typedef CGAL::Exact_predicates_inexact_constructions_kernel K;typedef CGAL::Triangulation_2<K> Triangulation;
typedef Triangulation::Vertex_circulator Vertex_circulator;
typedef Triangulation::Point Point;int main()
{std::ifstream in("triangulation_prog1.cin");std::istream_iterator<Point> begin(in);std::istream_iterator<Point> end;Triangulation t;t.insert(begin, end);Vertex_circulator vc = t.incident_vertices(t.infinite_vertex()),done(vc);if (vc != nullptr) {do {std::cout << vc->point() << std::endl;} while (++vc != done);}return 0;
}
4.5 Draw a 2D Triangulation
可以通过调用CGAL::draw<T2>()
函数来可视化二维三角剖分,如下例所示。该函数打开一个新窗口,显示给定的2D三角剖分。对这个函数的调用是阻塞的,也就是说,只要用户关闭窗口,程序就会继续。
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Triangulation_2.h>
#include <CGAL/draw_triangulation_2.h>
#include <fstream>typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_2<K> Triangulation;
typedef Triangulation::Point Point;int main(int argc, char* argv[]) {std::ifstream in((argc>1)?argv[1]:"data/triangulation_prog1.cin");std::istream_iterator<Point> begin(in);std::istream_iterator<Point> end;Triangulation t;t.insert(begin, end);CGAL::draw(t);return EXIT_SUCCESS;
}
此函数需要CGAL_Qt5
,并且仅在定义了宏CGAL_USE_BASIC_VIEWER
时可用。链接到cmake目标CGAL::CGAL_Basic_viewer
将链接到CGAL_Qt5
并添加定义CGAL_USE_BASIC_VIEWER
。
5 Delaunay Triangulations
5.1 Description
类Delaunay_triangulation_2<Traits,Tds>
用来表示平面上一组数据点的Delaunay三角剖分。Delaunay三角剖分满足以下空圆性质(也称为Delaunay性质):三角剖分的任何面的围合圆内部不包含任何数据点。对于没有四个共圆点子集的点集,Delaunay三角剖分是唯一的,它与点集的Voronoi图是对偶的。类Delaunay_triangulation_2<Traits,Tds>
源自类Triangulation_2<Traits,Tds>
。类Delaunay_triangulation_2<Traits,Tds>
继承由基本类Triangulation_2<Traits,Tds>
定义的类型。traits
类提供的其他类型被定义为表示双重Voronoi图。类Delaunay_triangulation_2<Traits,Tds>
覆盖在三角剖分中插入、移动或移除点的成员函数,以维护Delaunay属性。它还有一个成员函数(Vertex_handle Delaunay_triangulation_2::nearest_vertex(const Point& p)
)来进行最近邻查询,还有一个成员函数来构造双Voronoi图的元素(顶点和边)。
5.2 Geometric Traits
几何特征类必须是概念DelaunayTriangulationTraits_2
的模型,它改进了概念TriangulationTraits_2
。特别地,这个概念提供了side_of_oriented_circle
谓词,给定四个点p,q,r,sp,q,r,sp,q,r,s,决定了点sss相对于经过ppp,qqq和rrr的圆的位置。side_of_oriented_circle
谓词实际上定义了Delaunay三角剖分。更改这个谓词允许用户为不同的度量构建Delaunay三角剖分的变体,例如L1L_1L1或L∞L_{\infty}L∞度量或由凸对象定义的任何度量。然而,使用奇异度规的人必须小心,构造的三角剖分必须是凸包的三角剖分这意味着凸包的边必须是Delaunay边。这对于任何光滑凸度量(如L2L_2L2)都是允许的,对于其他度量(如L∞L_{\infty}L∞)也可以通过将精心选择的哨点添加到点集中来保证。CGAL内核类是欧氏度规的DelaunayTriangulationTraits_2
概念的模型。地形的traits
类,Projection_traits_xy_3<R>
, Projection_traits_yz_3<R>
和Projection_traits_xz_3<R>
也是DelaunayTriangulationTraits_2
的模型,除非它们不满足对偶函数和最近顶点查询的要求。
5.3 Implementation
在Delaunay三角剖分中插入一个新点,首先使用基本三角剖分的插入成员函数,然后执行一系列翻转以恢复Delaunay属性。如果新顶点在更新的Delaunay三角剖分中度为ddd,则必须执行的翻转次数为O(d)O(d)O(d)。对于均匀随机分布的点,每次插入平均花费时间O(1)O(1)O(1),一旦点被定位在三角剖分中。
移除调用三角剖分中的移除,然后以满足Delaunay准则的方式重新三角剖分创建的孔。移除度为ddd的顶点需要时间O(d2)O(d^2)O(d2)对于三角剖分中的一个随机顶点,度ddd为O(1)O(1)O(1)。当被移除顶点的程度很小(≤7\leq7≤7)时,使用一种特殊的程序,允许将随机点的全局移除时间减少2倍。
将点ppp的顶点vvv 移动到新位置p′p'p′,首先检查将vvv移动到p′p'p′ 后三角嵌入是否保持平面。如果是,它将vvv移动到p′p'p′,并简单地执行一系列翻转来恢复Delaunay属性,时间复杂度为O(d)O(d)O(d),其中ddd是位移后顶点的度数。否则,置换是通过在新位置插入一个顶点,并删除原始的顶点来完成的。在最坏的情况下,复杂度为O(n)O(n)O(n),但对于单位正方形中均匀分布的顶点,复杂度仅为O(1+δ√n)O(1+δ√n)O(1+δ√n),其中δδδ为新位置和旧位置之间的欧氏距离。在完成点定位之后,在最坏的情况下,找到点的最近邻居时间复杂度为O(n)O(n)O(n),但对于均匀随机分布的顶点和任何查询点,时间复杂度为O(1)O(1)O(1)。
5.4 Example: a Delaunay Terrain
下面的代码为地形模型的垂直投影使用常用的欧氏度规创建Delaunay三角剖分。这些点有高程,也就是说它们是3D点,但用于构建Delaunay三角剖分的谓词只使用这些点的xxx和yyy坐标计算。
类Projection_traits_xy_3<K>
是2D和3D线性几何核的一部分。
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h> // 内核
#include <CGAL/Projection_traits_xy_3.h> // xy投影面
#include <CGAL/Delaunay_triangulation_2.h> // Delaunay三角剖分#include <fstream>typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Projection_traits_xy_3<K> Gt;
typedef CGAL::Delaunay_triangulation_2<Gt> Delaunay;typedef K::Point_3 Point;int main()
{std::ifstream in("terrain.cin");std::istream_iterator<Point> begin(in);std::istream_iterator<Point> end;Delaunay dt(begin, end);std::cout << dt.number_of_vertices() << std::endl;return 0;
}
5.5 Example: Voronoi Diagram
下面的代码计算一组数据点的Voronoi图的边,并计算该图的有限边数和射线数
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>#include <fstream>typedef CGAL::Exact_predicates_inexact_constructions_kernel K;typedef CGAL::Delaunay_triangulation_2<K> Triangulation;
typedef Triangulation::Edge_iterator Edge_iterator;
typedef Triangulation::Point Point;int main()
{std::ifstream in("voronoi.cin");std::istream_iterator<Point> begin(in);std::istream_iterator<Point> end;Triangulation T;T.insert(begin, end);int ns = 0;int nr = 0;Edge_iterator eit = T.edges_begin();for (; eit != T.edges_end(); ++eit) {CGAL::Object o = T.dual(eit);if (CGAL::object_cast<K::Segment_2>(&o)){++ns;}else if (CGAL::object_cast<K::Ray_2>(&o)) { ++nr;}}std::cout << "The Voronoi diagram has " << ns << " finite edges "<< " and " << nr << " rays" << std::endl;return 0;
}
5.6 Example: Print Voronoi Diagram Edges Restricted to a Rectangle
下面的代码计算一组点的Delaunay三角剖分,并打印受给定矩形限制的Voronoi边。
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <iterator>typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point_2;
typedef K::Iso_rectangle_2 Iso_rectangle_2;
typedef K::Segment_2 Segment_2;
typedef K::Ray_2 Ray_2;
typedef K::Line_2 Line_2;
typedef CGAL::Delaunay_triangulation_2<K> Delaunay_triangulation_2;//A class to recover Voronoi diagram from stream.
//Rays, lines and segments are cropped to a rectangle
//so that only segments are stored
struct Cropped_voronoi_from_delaunay {std::list<Segment_2> m_cropped_vd;Iso_rectangle_2 m_bbox;Cropped_voronoi_from_delaunay(const Iso_rectangle_2& bbox) :m_bbox(bbox) {}template <class RSL>void crop_and_extract_segment(const RSL& rsl) {CGAL::Object obj = CGAL::intersection(rsl, m_bbox);const Segment_2* s = CGAL::object_cast<Segment_2>(&obj);if (s) m_cropped_vd.push_back(*s);}void operator<<(const Ray_2& ray) { crop_and_extract_segment(ray); }void operator<<(const Line_2& line) { crop_and_extract_segment(line); }void operator<<(const Segment_2& seg) { crop_and_extract_segment(seg); }
};int main() {//consider some pointsstd::vector<Point_2> points;points.push_back(Point_2(0, 0));points.push_back(Point_2(1, 1));points.push_back(Point_2(0, 1));Delaunay_triangulation_2 dt2;//insert points into the triangulationdt2.insert(points.begin(), points.end());//construct a rectangleIso_rectangle_2 bbox(-1, -1, 2, 2);Cropped_voronoi_from_delaunay vor(bbox);//extract the cropped Voronoi diagramdt2.draw_dual(vor);//print the cropped Voronoi diagram as segmentsstd::copy(vor.m_cropped_vd.begin(), vor.m_cropped_vd.end(),std::ostream_iterator<Segment_2>(std::cout, "\n"));
}
6 Regular Triangulations
6.1 Description
未完待续……
相关文章:

CGAL 二维剖分
目录一、 2D Triangulations1、定义2 Representation2.1 The Set of Faces2.2 A Representation Based on Faces and Vertices3 Software Design4 Basic Triangulations4.1 Description遍历三角网顶点4.2 Implementation4.3 Geometric Traits4.4 Example of a Basic Triangulat…...

node.js+vue婚纱影楼摄影婚庆管理系统vscode项目
:减少管理婚庆工作人员的负担;管理人员可以随时浏览婚纱网站以便及时知道哪里需要修改和更进,同时还可以查看用户反馈给我们的信息,让管理员更加直观的了解客户的需求;该系统改变了以前手工记录的方式,使用…...
C语言 指针的新理解
16年写了很多 C 与 C 相关的文章,但是后面从事了 Android 开发,就全部删掉了,无意中发现了这篇由还存在草稿箱,索性就找回来吧,也是追忆当年学习的青葱岁月 1.指针就是一个存储了其他变量地址的变量。 指针存储的是整…...

【向每个应用View中增加子控件 Objective-C语言】
一、把刚才计算九宫格的思路再给大家过一遍 1.现在我们要计算九宫格坐标 1)先把每一个格子,每一个九宫格的大小,先确定了, 在这里先指定宽和高 CGFloat appW = 75; CGFloat appH = 90; 2)再去计算第一个格子的一些间距, 到上面的间距,marginTop = 30; 再计算出…...

【FPGA】Verilog:组合电路设计 | 三输入 | 多数表决器
前言:本章内容主要是演示Vivado下利用Verilog语言进行电路设计、仿真、综合和下载的示例:表决器(三人表决器)。 功能特性: 采用 Xilinx Artix-7 XC7A35T芯片 配置方式:USB-JTAG/SPI Flash 高达100MHz 的内部…...

【安全等保】安全等保二级和三级哪个高?哪个费用更高?
等保政策已经严格落地执行了,各大企业纷纷接到了过等保的通知,但有的估计是第一次听到等保,对于等保相关政策都是非常蒙圈的。这不不少企业相关负责人在问,安全等保二级和三级哪个高?哪个费用更高?这里我们…...
C++ STL学习记录(v1)
C STL学习记录一. 什么是STL1.1 STL的诞生1.2 STL基本概念1.3 STL的六大组件1.4 STL中的容器、算法、迭代器1.5 容器、算法、迭代器实践一. 什么是STL 1.1 STL的诞生 STL建立的目的就是为了解决软件界复用性的需求。C的面向对象和泛型编程思想,目的就是为了复用性的…...
开发中遇到的问题
1.当写一个导出功能时,因为编码写URL地址&参数的时候,用反转字符串的时候换行了,造成地址拼接不成,一直报错,后来发现是编码格式造成的,已解决。 解决方案:不换行或者用 “”拼接 2.当本地…...
Javascript笔记
数据类型 基本类型(primitive value) 简单的数据段,包括 Undefined, Null, Boolean, Number, String初始化只使用2原始字面量形式,如果使用new则会创建Object无法加入新的属性 引用类型(reference value) 可能由多个值构成的对象判断类型 typeofinstanc…...
Elasticsearch(ES)配置及优化
在Elasticsearch中,索引的大小和存储能力取决于多个因素,包括文档大小、索引的分片数、硬件规格、查询负载和其他因素。索引和分片配置:索引和分片的数量和配置会对查询并发性能产生影响。如果索引和分片的数量太少,可能会导致查询…...

一文看懂Java语言与Java生态圈
Java语言与Java生态圈 1、Oracle JDK与Open JDK之间的关系 Oracle JDK Java最早是由SUN公司发明,Oracle JDK之前叫SUN JDK,显而易见,这是在2009年Oracle收购SUN公司之前,收购之后被名为Oracle JDK,实际上࿰…...
GitHub 上有什么嵌入式方面的项目?
原文直达,喜欢就点个赞吧! GitHub 上有什么嵌入式方面的项目? - CodeAllen的回答 - 知乎 https://www.zhihu.com/question/27835930/answer/2871624679 前言 对于GitHub,可能做互联网开发的同学会更加熟悉,尤其是前端࿰…...

【C语言进阶】结构体、位段、枚举和联合
👦个人主页:Weraphael ✍🏻作者简介:目前是C语言学习者 ✈️专栏:C语言航路 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你有帮助的话 欢迎 评论💬 点赞&a…...
markdown和latex常用部分参考@注脚@链接跳转@csdn
文章目录refmarkdown和latex常用部分参考typora文档基础语法扩展语法链接内联链接的方式将链接提取出来链接示例typora的支持LinksInline LinksInternal Links🎈Reference LinksURLs文章内部跳转(Heading IDs)🎈My Great Heading注脚(Footnotes)…...

Java 在二叉树中增加一行
623. 在二叉树中增加一行中等给定一个二叉树的根 root 和两个整数 val 和 depth ,在给定的深度 depth 处添加一个值为 val 的节点行。注意,根节点 root 位于深度 1 。加法规则如下:给定整数 depth,对于深度为 depth - 1 的每个非空树节点 cur…...

kubernetes(k8s) 知识总结(第2期)
1. “控制器”思想 kube-controller-manager 是一系列控制器的集合,这些控制器被放在 Kubernetes 项目的 pkg/controller 目录,这些控制器都以独有的方式负责某种编排功能。它们都遵循一个通用的编排模式——控制循环。 以 Deployment 为例介绍它对控…...

windows-Mysql的主从数据库同步设置
复制原有的mysql修改my.ini配置文件 修改端口号修改从数据的地址和从数据库的数据存放地址安装从数据库进入从数据库的bin目录,打开命令窗口输入命令:mysqld.exe install mysql-back --defaults-file "C:\ProgramData\MySQL\MySQL Server 5.7-back\…...

Docker逃逸
文章目录原理环境搭建Docker 环境判断Docker 容器逃逸特权模式逃逸如何判断是否为特权模式逃逸docker.sock挂载逃逸逃逸Remote API未授权访问未授权访问逃逸容器服务缺陷逃逸影响版本环境搭建逃逸脏牛漏洞逃逸参考原理 docker其实就是一个linux下的进程,它通过Name…...
k8s项目部署
k8s命令k8s项目部署部署流程实现导出相应的yaml文件 kubectl create deployment 名字--image镜像-o yaml --dry-runclient > 文件名 例: kubectl create deployment nginx --imagenginx -o yaml --dry-runclient > m1.yaml导出已经部署后的yaml文件 kubectl g…...

Modbus通信协议学习笔记
Modbus主从设备 主控设备(Modbus Master):工控机、PLC、触摸屏等等 从设备(Modbus Slave):PLC、Modbus采集模块、带485通讯的传感器、仪器仪表等等 Modbus物理接口:串口(RS232、RS4…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...

欢乐熊大话蓝牙知识17:多连接 BLE 怎么设计服务不会乱?分层思维来救场!
多连接 BLE 怎么设计服务不会乱?分层思维来救场! 作者按: 你是不是也遇到过 BLE 多连接时,调试现场像网吧“掉线风暴”? 温度传感器连上了,心率带丢了;一边 OTA 更新,一边通知卡壳。…...
Vuex:Vue.js 应用程序的状态管理模式
什么是Vuex? Vuex 是专门为 Vue.js 应用程序开发的状态管理模式 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 在大型单页应用中,当多个组件共享状态时,简单的单向数据流…...
React 样式方案与状态方案初探
React 本身只提供了基础 UI 层开发范式,其他特性的支持需要借助相关社区方案实现。本文将介绍 React 应用体系中样式方案与状态方案的主流选择,帮助开发者根据项目需求做出合适的选择。 1. React 样式方案 1.1. 内联样式 (Inline Styles) 通过 style …...
NamedParameterJdbcTemplate 使用方法及介绍
NamedParameterJdbcTemplate是 Spring 框架中用于数据库操作的核心类之一,它拓展了JdbcTemplate,通过封装实现命名参数特性,相比传统占位符?,命名参数可读性和维护性更强,能有效避免参数顺序混淆问题。 一、核心支持…...