本章介绍了CGAL的二维三角剖分。定义部分回顾了关于三角剖分的主要定义。表示部分讨论了二维三角剖分在CGAL中的表示方式。软件设计部分介绍了二维三角剖分包的总体软件设计。接下来的部分介绍了CGAL中可用的不同二维三角剖分类:基本三角剖分(基本三角剖分部分)、Delaunay三角剖分(Delaunay三角剖分部分)、规则三角剖分(规则三角剖分部分)、约束三角剖分(约束三角剖分部分)和约束Delaunay三角剖分(约束Delaunay三角剖分部分) 。上述需要认真了解的只用Delaunay三角剖分,其他三角剖分算法,目前可找到的文献较少。
具有约束和子约束之间双向映射的约束三角剖分部分描述了一个类,该类实现了一个约束或约束Delaunay三角剖分,并使用一个额外的数据结构来描述约束是如何被三角剖分的边细化的。三角剖分层次一节描述了用于快速点位置查询的分层数据结构。最后,灵活性一节解释了用户如何使用定制的面和顶点类从CGAL图形库的灵活性中受益。
1、定义
单形和复形是拓扑几何中的概念,其中单形是一种由仿射无关的顶点组构成的几何图形,而复形则是由单形构建的更复杂的几何图形。
具体来说,单形是由仿射无关的顶点组构成的几何图形,其中包括点、线段、三角形等。单形的边界算子决定了定向和奇偶性,即通过去掉一个定点,得到的顶点组依旧是仿射无关的,并且可以构成一个更低维度的单形。
而复形是由单形构建的更复杂的几何图形,通过将多个单形组合在一起,形成一个整体的几何形状。复形的构建可以不受度量的限制,只考虑形状的拓扑性质。例如,一个复形可以表示一个物体的表面,而单形则是构成该表面的小块几何图形。
在三角剖分中,奇点指的是在三角形的外接圆内,除了三角形顶点以外的其他点。这些点破坏了三角形的空圆性质,即一个三角形(或边)的外接圆范围内(边界除外),不包含点集P中的任何顶点。
二维三角剖分可以大致描述为三角面片的集合T,使得:两个面要么不相交,要么共享一个较低维度的面(边或顶点)。T中的一组面按邻接关系连接。作为T中面交集的域UT没有奇点。
更确切地说,三角剖分可以被描述为单形复形。让我们先记录一些定义。单形复形是单形的集合T,使得T中任何单形面都是T中的单形、T中的两个单形要么不相交,要么共享一个共同的子面(边)。
单形复体的维数d是其单形的最大维数。单纯复形T是纯的,如果T的任何单形都包含在具有最大维数的T的单形中。
如果两个最大维数为d的T中的单形共享一个d-1维子面,则它们被称为相邻。如果邻接关系定义了最大维数T的单形集合上的连通图,则单形复形是连通的。
三角形的连通性是指三角形中任意两点之间是否存在一条路径,使得这两点之间的路径上没有任何其他点。如果存在这样的路径,则称三角形是连通的。
在三角剖分中,连通性是指任何两个三角形顶点之间是否存在一条边连接它们。如果存在这样的边,则称这两个三角形是连通的。
T中所有单形的并UT称为T的域。如果T的域中的点p在UT中的周围既不是拓扑球也不是拓扑圆盘,则称其为奇点。然后,二维三角剖分可以被描述为纯的、连通的、没有奇点的二维单纯复形。
在三角剖分中,奇点指的是在三角形的外接圆内,除了三角形顶点以外的其他点。这些点破坏了三角形的空圆性质,即一个三角形(或边)的外接圆范围内(边界除外),不包含点集P中的任何顶点。
三角剖分的每个面都可以给出一个方向,这反过来又诱导了与该面相交的边的方向 。如果两个相邻面的方向在它们共同的相交边上是相反的,则这两个相邻面的方向是一致的。如果三角剖分的每个面的方向都可以这样选择,即所有成对的相交面都有一致的方向,则该三角剖分是可定向的。
CGAL中的Triangulation类可以用于处理二维和三维的三角剖分。 CGAL中的Triangulation类允许用户表示任何可定向二维三角剖分的组合,而不需要边界。在这个数据结构之上,二维三角剖分类负责三角剖分的几何嵌入,并被设计用于处理平面三角剖分。三角剖分的平面可以嵌入到更高维的空间中。
CGAL 的三角剖分是完整的三角剖分,这意味着它们的域是它们的顶点的凸包。 由于任何平面三角剖分都可以完成,这不是一个真正的限制。例如,多边形区域的三角剖分可以构造并表示为约束三角剖分的一个子集,其中区域边界边被输入为约束边(参见“约束三角剖分”,“约束Delaunay三角剖分”和“约束三角剖分,约束与子约束之间双向映射”)。
严格来说,术语面应该用于设计任何尺寸的面,三角形剖分的二维面应该被正确地称为小平面。但是,根据常见的用法,我们以后经常将面称为二维三角剖分的面。
2、表示
2.1、面集合
CGAL的2D三角剖分可以被视为一个平面分区,其有界面是三角形,覆盖了顶点集的凸包。这个分区的单个无界面是凸包的补集。在许多应用中,如Kirkpatrick的层次结构或增量Delaunay构造,只处理三角形面很方便。因此,一个名为无限顶点的虚拟顶点被添加到三角剖分中,以及与之相关的无限边和无限面。每个无限边都与无限顶点和凸包的一个顶点相交。每个无限面都与无限顶点和凸包的一个边相交。
因此,三角剖分的每个边都恰好与两个面相交,三角剖分的面集在拓扑上等价于二维球面。
请注意,无穷顶点没有重要的坐标,并且不能对它或无穷面应用几何谓词。
这延伸到退化情况下或当三角剖分具有少于三个顶点时出现的低维三角剖分。包括无限面,一维三角剖分是一个边缘和顶点环,拓扑上等价于一个1-球体。零维三角剖分,其域被简化为一个点,由两个顶点表示,拓扑上等价于一个0-球体。下图是具有零个、一个和两个有限顶点的三角形。
2.2、基于面和顶点的表示
由于三角剖分是一组具有恒定复杂度的三角形面,因此三角剖分不是作为平面地图之上的一个层来实现的。Cgal使用基于面和顶点而不是边的三角剖分的适当内部表示。这种表示节省了存储空间,并导致了更快的算法。
表示的基本元素是顶点和面。每个三角形面都可以访问它的三个入射顶点和它的三个相邻面。每个顶点都可以访问它的一个入射面,并通过该面访问它的入射面的循环列表。
面的三个顶点索引按逆时针顺序用0、1和2。面的邻居索引也用0、1、2,这样由i索引的邻居与具有相同索引的顶点相对。参见下图,该图所示的函数ccw(i)和cw(i)分别计算i+1和i-1模3。
边缘不是显式表示的,它们只是通过两个面的邻接关系隐式表示的。每条边都有两个隐式表示:与索引为i的顶点相对的面f的边,可以表示为f的邻居(i)的边。
3、软件设计
CGAL的三角剖分类提供了高级几何功能,例如三角剖分中点的位置、插入、删除或位移。它们被构建为称为三角剖分数据结构的数据结构之上的层。三角剖分数据结构可以被视为三角剖分面和顶点的容器。这个数据结构还负责三角剖分的所有组合方面。
几何方面和组合部分之间的这种分离在软件设计中反映为三角剖分类具有两个模板参数的事实:
第一个参数代表一个几何特征类 ,提供三角剖分的几何基元(点、线段和三角形)以及对这些对象的基本操作(谓词或构造)。
第二个参数代表三角剖分数据结构类 。三角剖分数据结构的概念在《二维三角剖分数据结构》一章的概念部分进行了描述。三角剖分数据结构定义了用于表示三角剖分面和顶点的类型,以及用于访问和访问面和顶点的其他类型(句柄、迭代器和循环器)。
CGAL提供了类 Triangulation_data_structure_2 作为三角剖分数据结构的默认模型。类 Triangulation_data_structure_2有两个模板参数,分别代表一个顶点类和一个面类。 CGAL为这些模板参数定义了概念,并为这些概念提供了默认模型。顶点和基类由几何特征类模板化,使其能够获得三角剖分的几何基元的一些知识。这些默认的顶点和面基类可以由用户自定义的基类替换,例如,为了处理附加到三角剖分的顶点或面的附加属性。有关如何利用这种灵活性的更多详细信息,请参阅“灵活性”一节。
总结了三角剖分包的设计,展示了构成该包的三层(基类、三角剖分据结构和三角剖分)。
负责三角剖分的几何嵌入的顶层三角剖分级别根据不同类型的三角剖分而有所不同:基本三角剖分、Delaunay三角剖分、规则三角剖分、约束三角剖分或约束Delaunay三角剖分。每种三角剖分对应于不同的类。下图总结了CGAL2D三角剖分类的派生依赖关系。任何2D三角剖分类都由几何特征类和三角剖分数据结构参数化。虽然唯一的概念TriangulationDataStructure_2描述了任何三角剖分类的三角剖分数据结构要求,但几何特征类的要求实际上取决于三角剖分类。一般来说,顶点和面基类要求由基本概念TriangulationVertexBase_2和TriangulationFaceBase_2描述。然而,一些三角剖分类要求基类实现基本概念的细化。
4、基础三角剖分
4.1、描述
类Triangulation_2是其他二维三角剖分类的基类,实现了三角剖分的用户接口。
三角剖分的顶点和面通过句柄、迭代器和循环器访问。 句柄是Handle概念的一个模型,它基本上提供了两个解引用运算符*和->。循环器是一种专门用于访问循环序列的类型。当访问的元素不属于序列时,使用句柄。迭代器和循环器用于访问三角剖分的全部或部分。
迭代器和循环器都是双向的,不可变的。循环器和迭代器可以转换为具有相同值类型的句柄,因此当调用成员函数时,任何句柄类型参数都可以替换为具有相同值类型的迭代器或循环器。
三角类提供了一个函数,可以按顺时针或逆时针顺序访问面的顶点和邻居。
循环器可以访问给定顶点或其相邻顶点所附着的边缘或面。另一种循环器类型可以访问给定线所经过的所有面。循环器既可以遍历无限特征,也可以遍历有限特征。
三角剖分类提供了一些迭代器来访问所有的面、边或顶点,以及有选择地访问有限的面、边或顶点的迭代器。
三角剖分类提供了测试任何特征的无限特征的方法,以及在给定其顶点的情况下测试特定特征(边或面)在三角剖分中的存在的方法。
三角剖分类提供了一种方法来定位给定点相对于三角形的位置。 特别是,该方法报告该点是否与三角形的顶点重合,是否位于边缘、面内或凸包外。 在退化的低维三角化的情况下,查询点也可能位于三角化仿射包络外。
三角剖分类还提供了相对于三角剖分的给定有限面或其外接圆定位点的方法。三角剖分的面及其外接圆具有逆时针方向。
三角剖分可以通过几个函数进行修改:插入点、删除顶点、移动顶点、翻转边。当两个入射面的并集形成一个凸四边形时,可以翻转边。
4.2、实施
定位是通过随机游走实现的。游走开始于三角剖分的一个顶点,该顶点作为可选参数给出,如果没有给出可选参数,则开始于三角剖分的任意顶点。对于Delaunay三角剖分,在最坏情况下需要O(n)的时间,但如果顶点随机均匀分布,则平均只需要O(n-√)。在三角剖分层次一节中描述的类Triangulation_hierarchy_2实现了一种数据结构,旨在提供一种更高效的点定位算法。
插入点是通过定位包含该点的面,并将该面分割成三个新面来完成的。如果该点落在凸包外,则通过翻转来恢复三角剖分。除了定位外,插入需要的时间为O(1)。这个界限只是对位于凸包外的点的平均时间界限。
删除一个顶点是通过删除所有相邻的三角形,并对孔进行重新三角化来实现的。删除所花费的时间最多与d2成正比,其中d是被删除顶点的度数,对于随机顶点,d为O(1)。
顶点的位移是通过以下方式完成的:首先,验证三角剖分嵌入在位移后是否保持平面;如果是,则将顶点直接放置在新位置;否则,在新位置插入一个点,并删除过时位置的顶点。
有限特征上的面、边和顶点迭代器是从它们访问所有(有限和无限)特征的对应迭代器中导出的,而这些迭代器本身又是由三角剖分数据结构的相应迭代器导出的。
4.3、几何特征
三角剖分的几何特征类需要提供构建三角剖分的几何对象(点、线段和三角形)以及这些对象的几何谓词。所需的谓词是:比较两个点的x或y坐标。方向测试,计算三个给定点顺序类型。
Triangulation_Traits_2概念描述了三角剖分的几何特征类的要求。CGAL内核类是该概念的模型。CGAL库还使用内核几何对象和谓词提供了Triangulation_Traits_2的专用模型。这些类本身由CGAL内核模板化,并从内核中提取所需的类型和谓词。Projection_traits_xy_3类是构建地形三角剖分的几何特征类。这样的三角剖分是嵌入在三维空间中的二维三角剖分。数据点是三维点。三角剖分是根据这些点在xy平面上的投影构建的,然后提升到原始的三维数据点。这对于处理GIS地形特别有用。特征类提供了忽略点 z 坐标的几何谓词,而不是真正投影三维点并保持每个点与其投影之间的映射(这会占用空间并容易出错)。请参阅 Delaunay Triangulations 部分以获取示例。
CGAL 库还提供了几何特征类 Projection_traits_yz_3 和 Projection_traits_xz_3,分别用于处理 yz 平面和 xz 平面上的投影,以及几何特征类 Projection_traits_3,用于处理由其正交向量定义的任意平面上的投影。//除了这些几何特征类,其他的很少见。
4.4、绘制2D的三角剖分
通过调用的CGAL::draw()函数,可以可视化2D三角剖分。此函数打开一个新窗口,显示给定的2D三角剖分。调用此函数是阻塞的,即一旦用户关闭窗口,程序就会继续。
5、Delaunay三角剖分(重要)
Delaunay三角剖分是一种根据一组点生成三角剖分的方法。它的基本原则是保证所有三角形的外接圆内部不包含其他点。这样可以保证生成的三角剖分是最优的,即每个三角形都是尽可能小的。
在Delaunay三角剖分中,由于它的定义和特性,可能会增加顶点的数量。这是因为在生成三角剖分的过程中,为了确保满足Delaunay三角剖分的条件,可能会插入一些新的顶点。具体来说,当一组点进行Delaunay三角剖分时,可能会出现以下情况:如果某两个点之间的距离非常接近,那么在它们之间插入一个新的顶点可能会更有利于生成一个尽可能小的三角形。如果某两个三角形共享一条边,且这条边上的顶点不是两个三角形的顶点,那么将这个顶点从其中一个三角形移除,并在另一条边上插入一个新的顶点可能会生成更小的三角形。
因此,Delaunay三角剖分可能会增加顶点的数量,但这是为了确保生成的三角剖分是最优的。
5.1、描述
类 Delaunay_triangulation_2< Traits, Tds > 旨在表示平面上一组数据点的 Delaunay 三角剖分。 Delaunay 三角剖分满足以下空圆性质(也称为 Delaunay 性质):三角剖分任何面的外接圆在其内部不包含数据点。对于没有四个共圆点的子集的点集,Delaunay 三角剖分是唯一的,它是点集的 Voronoi 图的对偶。
类 Delaunay_triangulation_2< Traits,Tds> 派生自类 Triangulation_2< Traits,Tds>。
类 Delaunay_triangulation_2 继承了基本类 Triangulation_2 定义的类型。由 traits 类提供的其他类型被定义为表示对偶沃罗诺伊图。
类 Delaunay_triangulation_2< Traits,Tds> 重写了在三角剖分中插入、移动或删除点的成员函数,以保持 Delaunay 属性。它还有一个成员函数(Vertex_handleDelaunay_triangulation_2::nearest_vertex(const Point& p))来回答最近邻查询,以及构造对偶沃罗诺伊图的元素(顶点和边)的成员函数。
5.2、几何特征
几何特征类必须是概念DelaunayTriangulationTraits_2 的模型,该概念细化了概念TriangulationTraits_2。特别是,该概念提供了side_of_oriented_circle谓词,该谓词给定四个点p、q、r、s,确定了点s相对于通过p、q和r的圆的位置。side_of_oriented_circle谓词实际上定义了Delaunay三角剖分。改变该谓词允许用户为不同的度量构建Delaunay三角剖分的变体,例如L1或L∞度量或由凸物体定义的任何度量。但是,奇异度量的用户必须注意,所构造的三角剖分必须是凸壳的三角剖分,这意味着凸壳边缘必须是Delaunay边缘。这适用于任何平滑凸度量(如L2),并且可以通过在点集上添加精心选择的哨兵点来确保其他度量(如L∞)。
CGAL 核心类是欧几里得度量的 DelaunayTriangulation_Traits_2 概念的模型。 地形的 traits 类,Projection_traits_xy_3、Projection_traits_yz_3 和 Projection_traits_xz_3,也是 DelaunayTriangulation Traits_2 的模型,除了它们不满足对偶函数和最近顶点查询的要求。
5.3、实施
在Delaunay三角网中插入新点时,首先使用基本三角网的插入成员函数,然后执行一系列翻转以恢复Delaunay属性。如果新顶点在更新的Delaunay三角网中的度数为d,则必须执行的翻转次数为O(d)。对于随机均匀分布的点,一旦点位于三角网中,每次插入平均需要O(1)的时间。
移除操作会调用三角剖分中的移除操作,然后对由此产生的孔进行重新三角剖分,以满足Delaunay标准。移除度数为d的顶点需要O(d2)的时间。对于三角剖分中的随机顶点,度数为O(1)。当移除的顶点度数较小(≤7)时,会使用一种特殊程序,使随机点的全局移除时间减少2倍。
将点p处的顶点v移位到新位置p',首先检查三角剖分嵌入在将v移动到p'后是否保持平面。如果是,则将v移动到p'并简单地执行一系列翻转以恢复Delaunay属性,其中d是位移后的顶点度。否则,通过在新位置插入一个顶点并删除过时的顶点来完成位移。在最坏的情况下,复杂度为O(n),但对于单位方块中均匀分布的顶点,只有O(1+δn−−√),其中δ是新旧位置之间的欧几里德距离。
执行点定位后,在最坏情况下,点的最近邻居可以在O(n)时间内找到,但对于随机均匀分布的顶点和任何查询点,可以在O(1)时间内找到。
6、规则三角剖分
正则三角剖分是一种特殊的三角剖分,它对于给定的点集,通过特定的规则构建出满足一定条件的三维凸包。具体来说,正则三角剖分是将一个有限点集V映射到一个凸多胞形,该多胞形的每个面都是一个三角形,且所有三角形的合集是散点集V的凸包。
6.1、描述
令 PW = {(pi,wi)|i=1,…,n} 为一组加权点,其中每个 pi 都是一个点,每个 wi 都是一个标量,称为点 pi 的权重。或者,每个加权点 (pi,wi) 可以被视为一个球体(或圆,取决于 pi 的维度),其中心为 pi,半径为 ri=根号wi。
集合PW的幂图是一个空间划分,其中每个单元对应于PW中的一个球体(pi,wi),并且是点p的轨迹,点p相对于(pi,wi)的幂小于它相对于PW中任何其他球体的幂。在二维空间中,该图的对偶是一个三角剖分,其域覆盖中心点集合P={pi|i=1,…,n}的凸包,其顶点构成P的一个子集。这样的三角剖分称为正则三角剖分。如果平面上的三个点pi、pj和pk在PW的正则三角剖分中形成三角形,则存在一个点p,其相对于(pi,wi)、(pj,wj)和(pk,wk)的幂相等,并且该幂小于p相对于PW中任何其他球体的幂。
类Regular_triangulation_2旨在维护一组二维加权点的正三角形。它从类Triangulation_2派生而来。函数insert和remove被重写以处理加权点并保持正三角形属性。函数move()没有被重写,因此不保留正三角形属性。一组加权点PW的正三角形的顶点仅对应于PW的子集。一些输入加权点在双幂图中没有单元,因此不对应于正三角形的顶点。这样的点称为隐藏点。因为隐藏点在以后某个点被删除时可能作为顶点重新出现,所以它们必须存储在某个地方。正三角形将这些点存储在称为隐藏顶点的特殊顶点中。只有当隐藏它的二维面从三角剖分中删除时,隐藏点才会重新出现为三角剖分的顶点。为了处理这个特性,规则三角剖分的每个面都存储一个隐藏顶点列表。当面被删除时,这些顶点中的点会重新插入三角剖分中。
常规三角剖分具有构造对偶功率图的顶点和边的成员函数。
6.2、几何特征
正三角剖分的几何特征类必须提供加权点类型和对这些加权点的幂测试。概念RegularTriangulationTraits_2是对概念TriangulationTraits_2的改进。所有CGAL内核都是特征概念RegularTriangulationTraits_2的模型。
6.3、正则三角剖分的顶点类型和面类型
正则三角剖分的基顶点类型包含一个布尔数据成员来标记顶点的隐藏状态。因此,CGAL定义了RegularTriangulationVertexBase_2的概念,该概念对TriangulationVertexBase_2的概念进行了细化,并为该概念提供了一个默认模型。
正则三角剖分面基类型需要提供隐藏顶点列表,用于存储被面隐藏的点。它必须是概念 RegularTriangulationFaceBase_2 的模型。 CGAL几何提供模板类 Regular_triangulation_face_base_2< Traits > 作为正三角剖分面的默认基类。
7、约束三角剖分
约束三角剖分是指一组点的三角剖分,其边中必须包含一组连接这些点的给定折线。这些折线称为约束。相应的边称为约束边。
受约束边的端点当然是三角剖分的顶点。但是,三角剖分也可能包括其他顶点。受约束三角剖分有三个版本。
在这些版本中,输入约束可能由相交、重叠或部分重叠的线段组成。三角剖分在每个点处引入了额外的顶点,这些点是两个约束的适当交点。单个约束与其他约束相交,将在三角剖分中显示为多个受约束的边。有两种方法可以处理相交约束。 当谓词被精确计算时,第一个是鲁棒的,但构造(即交集计算)是近似的。 第二个应该使用精确算法(这意味着对谓词的精确评估和对交集的精确计算)。
7.1、几何特征
约束三角剖分的几何特征类必须是概念TriangulationTraits_2的模型。当支持输入约束的交集时,几何特征类必须是概念ConstrainedTriangulationTraits_2 的模型,该模型对概念TriangulationTraits_2进行了细化,提供了额外的函数对象类型来计算两个线段的交集。
7.2、约束三角剖分的面基类
关于约束边的信息存储在三角剖分中。约束三角剖分的面基必须是概念ConstrainedTriangulationFaceBase_2 的模型,该概念对概念TriangulationFaceBase_2进行了细化。概念ConstrainedTriangulationFaceBase_2需要成员函数来获取和设置边的约束状态。
CGAL为约束三角剖分提供了一个默认的面基类。这个名为Constrained_triangulation_face_base_2的类从Triangulation_face_base_2类派生而来,并添加了三个布尔数据成员来存储其边的状态。
8、约束Delaunay三角剖分
约束Delaunay三角剖分和Delaunay三角剖分的主要区别在于约束的存在与否。
Delaunay三角剖分是一种离散分布的点集P的三角剖分,它使得点集P中没有任意一个点严格处于任意一个三角形的外接圆的内部。这种三角剖分构建的三角网可以尽量避免狭长三角形的出现,有效提高逼近精度,使得网格整体质量保持最优。
约束Delaunay三角剖分则是在Delaunay三角剖分的基础上引入了约束条件。这些约束条件可以包括点集的边界或其他特定要求,如特定的三角形形状或大小等。这种类型的三角剖分不是任意的,而是受到特定约束的限制。
另外,约束Delaunay三角剖分的构建过程可能比Delaunay三角剖分更为复杂,因为它需要在满足约束条件的前提下,尽可能地优化三角形的形状和质量。因此,在实际应用中,需要根据具体需求和数据特点来选择是否采用约束Delaunay三角剖分。
受约束的Delaunay三角剖分是一种具有约束边的三角剖分,这些约束边尽可能地接近Delaunay三角剖分。由于约束边不一定是Delaunay边,因此受约束的Delaunay三角剖分的三角形不一定满足空圆性质,但它们满足较弱的约束空圆性质 。然后,三角剖分是受约束的Delaunay三角剖分,只要任何面的外接圆不包含从该面内部可见的顶点。与受约束的三角剖分的情况一样,提供了三种不同版本的Delaunay受约束三角剖分。第一个版本处理一组约束,这些约束除了端点外不相互交叉。另外两个版本处理相交的输入约束。其中一个版本的设计是,当与提供精确谓词和近似构造的几何特征类(如Filtered_kernel或任何提供过滤精确谓词的核)结合使用时,它具有鲁棒性。第三个版本的设计是,与精确算术数字类型一起使用。
CGAL类 Constrained_Delaunay_triangulation_2 旨在表示受约束的 Delaunay 三角剖分。
与约束三角剖分的情况一样,第三个参数 Itag 是交点标记,用于选择如何处理相交约束。 它可以用以下类之一实例化:No_constraint_intersection_tag、No_constraint_intersection_requiring_constructions_tag、Exact_predicates_tag 或 Exact_intersections_tag(见“约束三角剖分”一节)。
受约束的 Delaunay 三角剖分不是 Delaunay 三角剖分,但它是一种受约束的三角剖分。 因此,Constrained_Delaunay_triangulation_2 类从 Constrained_triangulation_2 类派生而来。
受约束的Delaunay三角剖分具有成员函数,可以覆盖点或约束的插入和删除。每个成员函数都负责恢复受约束的空圆属性。
8.1、几何特征类
受约束的Delaunay三角剖分的几何特征类需要提供side_of_oriented_circle谓词作为Delaunay三角剖分的几何特征类,并且必须是概念DelaunayTriangulationTraits_2 的模型。当支持输入约束相交时,进一步要求几何特征类提供函数对象来计算约束相交。然后,几何特征类必须同时是概念ConstrainedTriangulation Traits_2的模型。
8.2、Face基类
有关三角剖分边状态(受约束或不受约束)的信息必须存储在面类中,受约束的Delaunay三角剖分的面基类必须是ConstrainedTriangulationFaceBase_2 的模型。
9、约束和次约束之间双向映射的约束三角剖分
本节对约束的管理
Constrained_triangulation_plus_2
类提供了一个具有附加数据结构的约束三角剖分,该数据结构跟踪输入约束及其在三角剖分中的细化。 Constrained_triangulation_plus_2 类继承自其模板参数 Tr,该参数必须由约束或约束的 Delaunay 三角剖分实例化。 根据其交点标记,基类将支持或不支持相交输入约束。 当支持输入约束的相交时,基类将构造约束排列的三角剖分,在每个适当的交点处引入新的顶点。
三角剖分将为每个输入约束保留此约束上的顶点序列。这些顶点或者是输入约束的顶点,或者是交点。
输入约束的两个连续顶点形成一个子约束。三角剖分使得可以检索三角剖分的子约束集(不是沿着约束排序的)。
它进一步允许检索出诱导子约束的输入约束集。由于从受约束的边e中直接获得子约束是很容易的,因此可以很容易地获得诱导e的输入约束。
9.1、边、受约束的边、约束和子约束
所有三角剖分类都将类型 Edge 定义为 typedef std::pair Edge。对于一个 pair (fh,i),它是面 *fh 的边,与第 i 个顶点相对。
受约束的边 e 是受约束三角剖分 ct 的边,对于该边,ct.is_constrained(e) 返回 true。
约束是作为输入给出的折线(在最简单的情况下只是一个线段),在三角剖分中它被分割成受约束的边。
Subconstraint类型被定义为typedef std::pair Subconstraint。这两个顶点句柄必须是受约束边的顶点。
Constraint_id类型标识约束。
所有受约束的CGAL类都提供了插入约束的功能,具有受约束边的概念,并提供Constrained_edges_iterator。
Constrained_triangulation_plus_2 类还额外提供了以下方法
使用类型为Constraint_iterator的迭代器遍历三角剖分的所有约束,其值类型为Constraint_id,获取所有导致约束边或子约束的约束,使用 Vertices_in_constraint_iterator 类型的迭代器遍历约束的顶点序列,其值类型为 Vertex_handle
使用 Subconstraint_iterator 类型的迭代器遍历三角剖分中的子约束,其值类型为 Subconstraint。
请注意,Constrained_edges_iterator 和 Subconstraint_iterator 非常相似。Constrained_edges_iterator 遍历所有边并跳过不受约束的边,这意味着遍历时间将与总边数呈线性关系。而 Subconstraint_iterator 遍历三角剖分中存储的一组子约束。
另一方面,由于子约束只是一对顶点控制柄,确定相应的边需要两个顶点中较小的一个度数,而从子约束中获取边是一个常数时间操作。
9.2、交叉点标记
当基础约束三角剖分类处理约束的交集并使用精确数字类型时,即当其交集标签为 Exact_intersections_tag 时,Constrained_triangulation_plus_2
类特别有用。在这种情况下,Constrained_triangulation_plus_2 避免了交集点计算中的级联。
插入约束时,例如三角剖分中的线段 s,该线段可能与约束边 e 相交,其顶点为 p 和 q。算法可以计算 s 与线段 [p,q] 的交点 i。由于这些点可能是先前构造的交点,如上图中的 q,最好使用诱导边的输入约束 c。如果 c 是线段,则算法将 s 与 c 相交。如果 c 是折线,则算法从输入约束中找出两个顶点,定义一个诱导边 e 的输入线段。
10、三角剖分层次
类Triangulation_hierarchy_2
实现了一个添加了数据结构的三角剖分,以有效地回答点位置查询。该数据结构是一个三角剖分的层次结构。最低级别的三角剖分是原始三角剖分,其中要执行操作和点位置。然后在每个后续级别,数据结构存储了前一级别三角剖分中顶点的小随机样本的三角剖分。 点位置是通过自上而下的最近邻查询完成的。最近邻查询首先在顶层三角剖分中朴素地执行。然后,在每个后续级别,通过从前一级别中找到的最近邻进行线性步行,找到该级别的最近邻。由于每个三角剖分中的顶点数量只是前一个三角剖分中顶点数量的一小部分,因此数据结构保持较小,并在真实数据上实现了快速点位置查询。当为Delaunay三角剖分构建时,这种结构具有最佳行为。但是,它也可以用于其他三角剖分,Triangulation_hierarchy_2 类由一个参数模板化,该参数由一个CGAL的三角剖分类实例化。
类 Triangulation_hierarchy_2
继承了作为模板参数 Tr 传递的三角剖分类型。插入、移动和删除成员函数被重写,以在每次操作时更新数据结构。定位查询也被重写,以利用数据结构进行快速处理。
10.1、三角剖分层次的顶点
三角剖分层次的基础顶点类必须是概念TriangulationHierarchyVertexBase_2的模型,该模型扩展了概念TriangulationVertexBase_2。 这一扩展为两个指针添加了访问和设置成员函数,这两个指针指向下一级和上一级三角剖分中相应的顶点。
CGAL 提供了 Triangulation_hierarchy_vertex_base_2 类,它是 TriangulationHierarchyVertexBase_2 概念的模型。该类由参数 Vb 模板化,该参数由 TriangulationVertexBase_2 概念的模型实例化。 Triangulation_hierarchy_vertex_base_2 类继承了其模板参数 Vb。这种设计允许使用默认的顶点类或用户自定义的顶点类,并为 Vb 提供额外的功能。
11、灵活性
本质是对三角剖分数据结构的顶点结构进行修改。
11.1、自定义的顶点和面
为了能够适应各种需求,我们为二维三角剖分选择了一种高度灵活的设计。我们已经看到,三角剖分类有两个参数:一个几何特征类和一个三角剖分数据结构类,用户可以使用自己的自定义类对其进行实例化。
然而,最实用的灵活性来自三角剖分数据结构本身有两个模板参数,需要用三角剖分的顶点和面的类来实例化。使用他自己的自定义类来实例化这些参数,用户可以轻松地构建一个包含顶点和面中附加信息或功能的三角剖分。
11.2、循环依赖
为了确保灵活性,三角剖分数据结构由顶点和面基类模板化。 此外,由于关联关系和邻接关系存储在顶点和面中,基类必须知道三角剖分数据结构提供的顶点和面上的句柄类型。因此,顶点和面基类本身必须通过三角测量数据结构进行参数化,并且存在对模板参数的循环依赖。
以前,这种循环依赖是通过在基类的接口中只使用void指针来避免的。这些void 在三角剖分数据结构级别上转换为适当的类型。这种解决方案有一些缺点:主要是用户无法在三角剖分的顶点或面上添加与三角剖分数据结构定义的类型相关的功能,例如一个顶点的句柄,他不得不使用void*指针。解决模板依赖性的新解决方案基于类似于标准分配器类std:: allocator中使用的机制的重新绑定机制。重新绑定机制在第二章《三角剖分数据结构》的“默认三角剖分数据结构”一节中进行了描述。现在,我们只注意到设计要求在顶点和面基类中存在一个嵌套的模板类Rebind_TDS,它定义了重新绑定机制使用的类型Other。
11.3、增加颜色
可以使用预定义的类Triangulation_vertex_base_with_info_2或Triangulation_face_base_with_info_2。这些类有一个模板参数Info,专门用于处理附加信息。
11.4、增加句柄
需要基于Triangulation_vertex_base_2类。
template < class Gt, class Vb = CGAL::Triangulation_vertex_base_2 >
class My_vertex_base
: public Vb
11.5、插入点范围时设置信息
在Delaunay(或规则)三角网中插入(加权)点最有效的方法是将(加权)点的迭代器范围提供给插入函数。但是,(加权)点的迭代器范围不允许用户为每个顶点设置不同的信息。为了解决这个问题,在三角网的顶点类型是TriangulationVertexBaseWithInfo_2 (如Triangulation_vertex_base_with_info_2)模型的情况下,我们提供了三个示例来执行相同的操作:将无符号整数设置为每个顶点的信息。这个无符号整数的值是范围中给定的对应点的初始顺序。
11.6、在pair上使用迭代器
typedef CGAL::Triangulation_vertex_base_with_info_2 Vb;
typedef CGAL::Triangulation_data_structure_2 Tds;
typedef CGAL::Delaunay_triangulation_2 Delaunay;
11.7、使用Boost压缩迭代器
boost::make_zip_iterator
是Boost库中的一个函数,它用于创建zip迭代器。Zip迭代器是一种可以同时遍历多个范围的迭代器。这些范围可以是同类型的,也可以是不同类型的。
Delaunay T;
T.insert( boost::make_zip_iterator(boost::make_tuple( points.begin(),indices.begin() )),
boost::make_zip_iterator(boost::make_tuple( points.end(),indices.end() ) ) );
11.8、使用Boost变换迭代器
boost::make_transform_iterator
是一个用于创建转换迭代器的函数,它属于Boost库的范围。转换迭代器是一种特殊类型的迭代器,可以将容器中的元素转换为另一种形式。
boost::make_transform_iterator
函数需要两个参数:一个输入迭代器和一个可调用对象(函数或函数对象),该对象定义了如何将输入迭代器指向的元素转换为另一种形式。
你可能感兴趣的:(CGAL,算法,几何学)
C++11堆操作深度解析:std::is_heap与std::is_heap_until原理解析与实践
文章目录堆结构基础与函数接口堆的核心性质函数签名与核心接口std::is_heapstd::is_heap_until实现原理深度剖析std::is_heap的验证逻辑std::is_heap_until的定位策略算法优化细节代码实践与案例分析基础用法演示自定义比较器实现最小堆检查边缘情况处理性能分析与实际应用时间复杂度对比典型应用场景与手动实现的对比注意事项与最佳实践迭代器要求比较器设计C++标
冒泡、选择、插入排序:三大基础排序算法深度解析(C语言实现)
xienda
算法 排序算法 数据结构
在算法学习道路上,排序算法是每位程序员必须掌握的基石。本文将深入解析冒泡排序、选择排序和插入排序这三种基础排序算法,通过C语言代码实现和对比分析,帮助读者彻底理解它们的差异与应用场景。算法原理与代码实现1.冒泡排序(BubbleSort)工作原理:通过重复比较相邻元素,将较大元素逐步"冒泡"到数组末尾。voidbubbleSort(intarr[],intn){ for(inti=0;iarr[
Leetcode 148. 排序链表
文章目录前引题目代码(首刷看题解)代码(8.9二刷部分看解析)代码(9.15三刷部分看解析)前引综合性比较强的一道题,要求时间复杂度必须O(logn)才能通过,最适合链表的排序算法就是归并。这里采用自顶向下的方法步骤:找到链表中点(双指针)对两个子链表排序(递归,直到只有一个结点,记得将子链表最后指向nullptr)归并(引入dummy结点)题目Leetcode148.排序链表代码(首刷看题解)c
全面触摸屏输入法设计与实现
长野君
本文还有配套的精品资源,点击获取简介:触摸屏输入法是针对触摸设备优化的文字输入方案,包括虚拟键盘、手写、语音识别和手势等多种输入方式。本方案通过提供主程序文件、用户手册、界面截图、示例图、说明文本和音效文件,旨在为用户提供一个完整的、多样的文字输入体验。开发者通过持续优化算法和用户界面,使用户在无物理键盘环境下也能高效准确地进行文字输入。1.触摸屏输入法概述简介在现代信息技术飞速发展的今天,触摸屏
FPGA小白到项目实战:Verilog+Vivado全流程通关指南(附光学类岗位技能映射)
阿牛的药铺
算法移植部署 fpga开发 verilog
FPGA小白到项目实战:Verilog+Vivado全流程通关指南(附光学类岗位技能映射)引言:为什么这个FPGA入门路线能帮你快速上岗?本文设计了一条**"Verilog语法→工具链操作→光学项目实战→岗位技能对标"的阶梯式学习路径。不同于泛泛而谈的FPGA教程,我们聚焦光学类产品开发**核心能力(时序接口设计、图像处理算法移植、高速接口应用),通过3个递进式项目(从LED闪烁到图像边缘检测),
PyTorch & TensorFlow速成复习:从基础语法到模型部署实战(附FPGA移植衔接)
阿牛的药铺
算法移植部署 pytorch tensorflow fpga开发
PyTorch&TensorFlow速成复习:从基础语法到模型部署实战(附FPGA移植衔接)引言:为什么算法移植工程师必须掌握框架基础?针对光学类产品算法FPGA移植岗位需求(如可见光/红外图像处理),深度学习框架是算法落地的"桥梁"——既要用PyTorch/TensorFlow验证算法可行性,又要将训练好的模型(如CNN、目标检测)转换为FPGA可部署的格式(ONNX、TFLite)。本文采用"
算法学习笔记:17.蒙特卡洛算法 ——从原理到实战,涵盖 LeetCode 与考研 408 例题
在计算机科学和数学领域,蒙特卡洛算法(MonteCarloAlgorithm)以其独特的随机抽样思想,成为解决复杂问题的有力工具。从圆周率的计算到金融风险评估,从物理模拟到人工智能,蒙特卡洛算法都发挥着不可替代的作用。本文将深入剖析蒙特卡洛算法的思想、解题思路,结合实际应用场景与Java代码实现,并融入考研408的相关考点,穿插图片辅助理解,帮助你全面掌握这一重要算法。蒙特卡洛算法的基本概念蒙特卡
算法学习笔记:15.二分查找 ——从原理到实战,涵盖 LeetCode 与考研 408 例题
呆呆企鹅仔
算法学习 算法 学习 笔记 考研 二分查找
在计算机科学的查找算法中,二分查找以其高效性占据着重要地位。它利用数据的有序性,通过不断缩小查找范围,将原本需要线性时间的查找过程优化为对数时间,成为处理大规模有序数据查找问题的首选算法。二分查找的基本概念二分查找(BinarySearch),又称折半查找,是一种在有序数据集合中查找特定元素的高效算法。其核心原理是:通过不断将查找范围减半,快速定位目标元素。与线性查找逐个遍历元素不同,二分查找依赖
LeetCode算法题:电话号码的字母组合
吱屋猪_
算法 leetcode java
题目描述:给定一个仅包含数字2-9的字符串,返回所有它能表示的字母组合。答案可以按任意顺序返回。给出数字到字母的映射如下(与电话按键相同)。注意1不对应任何字母。2->"abc"3->"def"4->"ghi"5->"jkl"6->"mno"7->"pqrs"8->"tuv"9->"wxyz"例如,给定digits="23",返回["ad","ae","af","bd","be","bf","cd
霍夫变换(Hough Transform)算法原来详解和纯C++代码实现以及OpenCV中的使用示例
点云SLAM
算法 图形图像处理 算法 opencv 图像处理与计算机视觉算法 直线提取检测 目标检测 霍夫变换算法
霍夫变换(HoughTransform)是一种经典的图像处理与计算机视觉算法,广泛用于检测图像中的几何形状,例如直线、圆、椭圆等。其核心思想是将图像空间中的“点”映射到参数空间中的“曲线”,从而将形状检测问题转化为参数空间中的峰值检测问题。一、霍夫变换基本思想输入:边缘图像(如经过Canny边缘检测)输出:一组满足几何模型的形状(如直线、圆)关键思想:图像空间中的一个点→参数空间中的一个曲线参数空
Java三年经验程序员技术栈全景指南:从前端到架构,对标阿里美团全栈要求
可曾去过倒悬山
java 前端 架构
Java三年经验程序员技术栈全景指南:从前端到架构,对标阿里美团全栈要求三年经验是Java程序员的分水岭,技术栈深度决定你成为“业务码农”还是“架构师候选人”。本文整合阿里、美团、滴滴等大厂招聘要求,为你绘制可落地的进阶路线。一、Java核心:从语法糖到JVM底层三年经验与初级的核心差异在于系统级理解,大厂面试常考以下能力:JVM与性能调优内存模型(堆外内存、元空间)、GC算法(G1/ZGC适用场
被动降噪的概念及编程实现
CodeByte
人工智能 算法 javascript 编程
被动降噪是指通过编程技术和算法,对输入的数据进行处理,以减少或消除其中的噪声。噪声可以是各种形式的干扰,例如来自传感器、通信信号或其他外部源的干扰。在本文中,我们将探讨被动降噪的意义以及如何使用编程来实现这一目标。被动降噪的意义:噪声对数据的准确性和可靠性产生负面影响。在许多应用领域,例如图像处理、音频处理和信号处理中,噪声的存在可能导致数据质量下降,使得后续的分析和处理变得困难。因此,被动降噪技
传统检测响应慢?陌讯多模态引擎提速90+FPS实战
2501_92473147
算法 计算机视觉 目标检测
开篇痛点:实时目标检测在安防监控中的核心挑战在安防监控领域,实时目标检测是保障公共安全的关键技术。然而,传统算法如YOLOv5或开源框架MMDetection常面临两大痛点:误报率高(复杂光照或遮挡场景下检测不稳定)和响应延迟(高分辨率视频流处理FPS低于30)。实测数据显示,城市交通监控系统误报率达15%,导致安保资源浪费;客户反馈表明,延迟超100ms时,目标跟踪可能失效。这些问题源于算法泛化
反光衣识别漏检率 30%?陌讯多尺度模型实测优化
在建筑工地、交通指挥等场景中,反光衣是保障作业人员安全的重要装备,对其进行精准识别是智能监控系统的核心功能之一。但传统视觉算法在实际应用中却屡屡碰壁:强光下反光衣易与背景混淆、远距离小目标漏检率高达30%、复杂场景下模型泛化能力不足[实测数据来源:某智慧工地项目2024年Q1日志]。这些问题直接导致安全监控系统预警滞后,给安全生产埋下隐患。一、技术解析:反光衣识别的核心难点与陌讯算法创新反光衣识别
【GESP】C++三级真题 luogu-B4359 [GESP202506 三级] 分糖果
CoderCodingNo
GESP c++ java 开发语言
GESPC++三级,2025年6月真题,模拟算法,难度★★☆☆☆。本次三级题目个人感觉比较简单。题目题解详见:【GESP】C++三级真题luogu-B4359[GESP202506三级]分糖果|OneCoder【GESP】C++三级真题luogu-B4359[GESP202506三级]分糖果|OneCoderGESPC++三级,2025年6月真题,模拟算法,难度★★☆☆☆。本次三级题目个人感觉比较
【华为机试】HJ61 放苹果
不爱熬夜的Coder
算法 华为机试 golang 华为 golang 算法 面试
文章目录HJ61放苹果描述输入描述输出描述示例1示例2解题思路算法分析问题本质分析状态定义与转移递推关系详解动态规划表构建算法流程图示例推导过程代码实现思路时间复杂度分析关键优化点边界情况处理递归解法对比实际应用场景测试用例分析算法特点数学原理完整题解代码HJ61放苹果描述我们需要将m个相同的苹果放入n个相同的盘子中,允许有的盘子空着不放。求解有多少种不同的分法。输入描述输入两个整数m,n(0B[
.NET中的安全性之数字签名、数字证书、强签名程序集、反编译
hezudao25
NET .net assembly 加密 算法 reference header
本文将探讨数字签名、数字证书、强签名程序集、反编译等以及它们在.NET中的运用(一些概念并不局限于.NET在其它技术、平台中也存在)。1.数字签名数字签名又称为公钥数字签名,或者电子签章等,它借助公钥加密技术实现。数字签名技术主要涉及公钥、私钥、非对称加密算法。1.1公钥与私钥公钥是公开的钥匙,私钥则是与公钥匹配的严格保护的私有密钥;私钥加密的信息只有公钥可以解开,反之亦然。在VisualStud
数据结构:导论
梁辰兴
数据结构 学习笔记 数据结构 导论 算法 时间复杂度 空间复杂度
目录一,数据结构的研究内容二,基本概念与术语(一)数据、数据元素、数据项与数据对象(二)数据结构(三)数据类型与抽象数据类型️三,抽象数据类型的表示与实现⚙️四,算法与算法分析⚖️(一)算法的定义及特性(二)评价算法优劣的基本标准⏱️(三)算法的时间复杂度(四)算法的空间复杂度章结一,数据结构的研究内容数据结构是计算机科学的核心基础,其研究内容可概括为三大维度:数据组织形式:探索如何将现实世界中的
C++ 标准库 <numeric>
以下对C++标准库中头文件所提供的数值算法与工具做一次系统、深入的梳理,包括算法功能、示例代码、复杂度分析及实践建议。一、概述中定义了一组对数值序列进行累加、内积、差分、扫描等操作的算法,以及部分辅助工具(如std::iota、std::gcd/std::lcm等)。所有算法均作用于迭代器区间,符合STL风格,可与任意容器或原始数组配合使用。从C++17、20起,又陆续加入了并行友好的std::r
具身语义导航算法总揽
Shilong Wang
具身导航算法 算法
端到端方法小脑大脑GNMNavDPNaVILAViNTNomadNavidStreamVLNMapNavNavGPTUni-NavidOctoNavNavGPT2模仿学习行为克隆BCDAgger模块化方法GOATVLFMSayPlanLM-NavETPNavVoroNavEmbodiedRAGVL-NavStairwaytoSuccess业内大佬北大王鹤NavidUni-NavidOctoNav吴
android去除gps漂移代码,GPS漂移过滤算法
扇贝君
GPS漂移过滤算法基本思想:逐点过滤,再经过基础过滤后,进行判断运动状态,静止状态和运动中。如果静止,则使用电子围栏;如果运动,则先过滤大速度,再过滤加速度,然后过滤距离(包括超大距离,和速度相关距离)。对于要过滤的点,采用之前最近的可靠点,进行替换,同时,无效次数+1,如果后面是有效点,则无效次数-1,如果无效次数归0,认为这个点才是真正可靠点(无效次数为正时,都为要被替换的点)。如果遇到不定点
项目开发日记
框架整理学习UIMgr:一、数据结构与算法1.1关键数据结构成员变量类型说明m_CtrlsList当前正在显示的所有UI页面m_CachesList已打开过、但现在不显示的页面(缓存池)1.2算法逻辑查找缓存页面:从m_Caches中倒序查找是否已有对应ePageType页面,找到则重用。页面加载:从资源管理器ResMgr加载prefab并绑定控制器/视图组件。页面关闭:从m_Ctrls移除,添加
深度学习图像分类数据集—桃子识别分类
AI街潜水的八角
深度学习图像数据集 深度学习 分类 人工智能
该数据集为图像分类数据集,适用于ResNet、VGG等卷积神经网络,SENet、CBAM等注意力机制相关算法,VisionTransformer等Transformer相关算法。数据集信息介绍:桃子识别分类:['B1','M2','R0','S3']训练数据集总共有6637张图片,每个文件夹单独放一种数据各子文件夹图片统计:·B1:1601张图片·M2:1800张图片·R0:1601张图片·S3:
《C++性能优化指南》 linux版代码及原理解读 第一章
v俊逸
C++性能优化指南 性能优化 C++性能优化 性能优化
概述:目录概述:性能优化的必要性:C++代码优化策略总结用好的编译器并用好编译器使用更好的算法使用更好的库减少内存分配和复制移除计算使用更好的数据结构提高并发性优化内存管理性能优化的必要性:按照当今的CPU运行速度来说,执行一条指令所需要的时间是10的-9次方的时间单位,如此快速的执行速度是否就没有性能优化的必要了呢?其实不然,性能优化与CPU的执行速度并无非常大的关系,试想一下,一段代码,如果用
《C++性能优化指南》 linux版代码及原理解读 第四章
v俊逸
C++性能优化指南 性能优化 C++性能优化指南 性能优化
目录概述为什么字符串很麻烦字符串是动态分配的字符串赋值背后的操作如何面对字符串会进行大量复制写时复制COW(copyonwrite)尝试优化字符串避免临时字符串通过预留存储空间减少内存分配通过传递引用减少实参复制使用迭代器操作减少循环中的比较操作减少返回值的复制还没有结束,使用字符数组代替字符串再次优化字符串尝试其他的算法叠加以前的优化方式使用其他的编译器使用其他字符串的库功能丰富的字符串库使用s
rtos内存管理
林内克思
java linux 算法
FreeRTOS将内存分配API保留在其可移植层,提供了五种内存管理算法:heap_1:最简单,不允许释放内存。heap_2:允许释放内存,但不会合并相邻的空闲块。heap_3:简单包装了标准malloc()和free(),以保证线程安全。heap_4:合并相邻的空闲块以避免碎片化。包含绝对地址放置选项。heap_5:如同heap_4,能够跨越多个不相邻内存区域的堆。特点缺点heap_1简单、不支
c++中迭代器的本质
三月微风
c++ 开发语言
C++迭代器的本质与实现原理迭代器是C++标准模板库(STL)的核心组件之一,它作为容器与算法之间的桥梁,提供了统一访问容器元素的方式。下面从多个维度深入解析迭代器的本质特性。一、迭代器的基本定义与分类迭代器的本质迭代器是一种行为类似指针的对象,用于遍历和操作容器中的元素。它提供了一种统一的方式来访问不同容器中的元素,而无需关心容器的具体实现细节。标准分类体系C++标准定义了5种迭代器类型,按功能
微算法科技的前沿探索:量子机器学习算法在视觉任务中的革新应用
MicroTech2025
量子计算 算法
在信息技术飞速发展的今天,计算机视觉作为人工智能领域的重要分支,正逐步渗透到我们生活的方方面面。从自动驾驶到人脸识别,从医疗影像分析到安防监控,计算机视觉技术展现了巨大的应用潜力。然而,随着视觉任务复杂度的不断提升,传统机器学习算法在处理大规模、高维度数据时遇到了计算瓶颈。在此背景下,量子计算作为一种颠覆性的计算模式,以其独特的并行处理能力和指数级增长的计算空间,为解决这一难题提供了新的思路。微算
目标检测中的NMS算法详解
好的,我们来详细解释一下目标检测中非极大值抑制(Non-MaximumSuppression,NMS)的相关概念和计算过程。1.为什么需要NMS?问题:目标检测模型(如FasterR-CNN,YOLO,SSD等)在推理时,对于同一个目标物体,通常会预测出多个重叠的、不同置信度(confidencescore)的候选边界框(BoundingBoxes)。直接输出所有这些框会导致:结果冗余:同一个物体
AI技术正在深刻重塑A/B测试优化的流程、效率和价值,推动其从传统的“手动实验”向“智能优化引擎”跃迁。
zzywxc787
人工智能
AI技术正在深刻重塑A/B测试优化的流程、效率和价值,推动其从传统的“手动实验”向“智能优化引擎”跃迁。以下是具体变革方向及实际影响:1.实验设计智能化:告别“猜猜看”传统痛点:依赖经验选择测试变量(如按钮颜色、文案),忽略潜在高价值组合。AI解决方案:多臂老虎机算法(MAB):动态分配流量至表现最优的变体(如:80%流量给当前最优,20%探索新选项),减少流量浪费高达70%(Netflix案例)
312个免费高速HTTP代理IP(能隐藏自己真实IP地址)
yangshangchuan
高速 免费 superword HTTP代理
124.88.67.20:843
190.36.223.93:8080
117.147.221.38:8123
122.228.92.103:3128
183.247.211.159:8123
124.88.67.35:81
112.18.51.167:8123
218.28.96.39:3128
49.94.160.198:3128
183.20
pull解析和json编码
百合不是茶
android pull解析 json
n.json文件:
[{name:java,lan:c++,age:17},{name:android,lan:java,age:8}]
pull.xml文件
<?xml version="1.0" encoding="utf-8"?>
<stu>
<name>java
[能源与矿产]石油与地球生态系统
comsci
能源
按照苏联的科学界的说法,石油并非是远古的生物残骸的演变产物,而是一种可以由某些特殊地质结构和物理条件生产出来的东西,也就是说,石油是可以自增长的....
那么我们做一个猜想: 石油好像是地球的体液,我们地球具有自动产生石油的某种机制,只要我们不过量开采石油,并保护好
类与对象浅谈
沐刃青蛟
java 基础
类,字面理解,便是同一种事物的总称,比如人类,是对世界上所有人的一个总称。而对象,便是类的具体化,实例化,是一个具体事物,比如张飞这个人,就是人类的一个对象。但要注意的是:张飞这个人是对象,而不是张飞,张飞只是他这个人的名字,是他的属性而已。而一个类中包含了属性和方法这两兄弟,他们分别用来描述对象的行为和性质(感觉应该是
新站开始被收录后,我们应该做什么?
IT独行者
PHP seo
新站开始被收录后,我们应该做什么?
百度终于开始收录自己的网站了,作为站长,你是不是觉得那一刻很有成就感呢,同时,你是不是又很茫然,不知道下一步该做什么了?至少我当初就是这样,在这里和大家一份分享一下新站收录后,我们要做哪些工作。
至于如何让百度快速收录自己的网站,可以参考我之前的帖子《新站让百
oracle 连接碰到的问题
文强chu
oracle
Unable to find a java Virtual Machine--安装64位版Oracle11gR2后无法启动SQLDeveloper的解决方案
作者:草根IT网 来源:未知 人气:813标签:
导读:安装64位版Oracle11gR2后发现启动SQLDeveloper时弹出配置java.exe的路径,找到Oracle自带java.exe后产生的路径“C:\app\用户名\prod
Swing中按ctrl键同时移动鼠标拖动组件(类中多借口共享同一数据)
小桔子
java 继承 swing 接口 监听
都知道java中类只能单继承,但可以实现多个接口,但我发现实现多个接口之后,多个接口却不能共享同一个数据,应用开发中想实现:当用户按着ctrl键时,可以用鼠标点击拖动组件,比如说文本框。
编写一个监听实现KeyListener,NouseListener,MouseMotionListener三个接口,重写方法。定义一个全局变量boolea
linux常用的命令
aichenglong
linux 常用命令
1 startx切换到图形化界面
2 man命令:查看帮助信息
man 需要查看的命令,man命令提供了大量的帮助信息,一般可以分成4个部分
name:对命令的简单说明
synopsis:命令的使用格式说明
description:命令的详细说明信息
options:命令的各项说明
3 date:显示时间
语法:date [OPTION]... [+FORMAT]
eclipse内存优化
AILIKES
java eclipse jvm jdk
一 基本说明 在JVM中,总体上分2块内存区,默认空余堆内存小于 40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。 1)堆内存(Heap memory):堆是运行时数据区域,所有类实例和数组的内存均从此处分配,是Java代码可及的内存,是留给开发人
关键字的使用探讨
百合不是茶
关键字
//关键字的使用探讨/*访问关键词private 只能在本类中访问public 只能在本工程中访问protected 只能在包中和子类中访问默认的 只能在包中访问*//*final 类 方法 变量 final 类 不能被继承 final 方法 不能被子类覆盖,但可以继承 final 变量 只能有一次赋值,赋值后不能改变 final 不能用来修饰构造方法*///this()
JS中定义对象的几种方式
bijian1013
js
1. 基于已有对象扩充其对象和方法(只适合于临时的生成一个对象):
<html>
<head>
<title>基于已有对象扩充其对象和方法(只适合于临时的生成一个对象)</title>
</head>
<script>
var obj = new Object();
表驱动法实例
bijian1013
java 表驱动法 TDD
获得月的天数是典型的直接访问驱动表方式的实例,下面我们来展示一下:
MonthDaysTest.java
package com.study.test;
import org.junit.Assert;
import org.junit.Test;
import com.study.MonthDays;
public class MonthDaysTest {
@T
LInux启停重启常用服务器的脚本
bit1129
linux
启动,停止和重启常用服务器的Bash脚本,对于每个服务器,需要根据实际的安装路径做相应的修改
#! /bin/bash
Servers=(Apache2, Nginx, Resin, Tomcat, Couchbase, SVN, ActiveMQ, Mongo);
Ops=(Start, Stop, Restart);
currentDir=$(pwd);
echo
【HBase六】REST操作HBase
bit1129
hbase
HBase提供了REST风格的服务方便查看HBase集群的信息,以及执行增删改查操作
1. 启动和停止HBase REST 服务 1.1 启动REST服务
前台启动(默认端口号8080)
[hadoop@hadoop bin]$ ./hbase rest start
后台启动
hbase-daemon.sh start rest
启动时指定
大话zabbix 3.0设计假设
ronin47
What’s new in Zabbix 2.0?
去年开始使用Zabbix的时候,是1.8.X的版本,今年Zabbix已经跨入了2.0的时代。看了2.0的release notes,和performance相关的有下面几个:
:: Performance improvements::Trigger related da
http错误码大全
byalias
http协议 javaweb
响应码由三位十进制数字组成,它们出现在由HTTP服务器发送的响应的第一行。
响应码分五种类型,由它们的第一位数字表示:
1)1xx:信息,请求收到,继续处理
2)2xx:成功,行为被成功地接受、理解和采纳
3)3xx:重定向,为了完成请求,必须进一步执行的动作
4)4xx:客户端错误,请求包含语法错误或者请求无法实现
5)5xx:服务器错误,服务器不能实现一种明显无效的请求
J2EE设计模式-Intercepting Filter
bylijinnan
java 设计模式 数据结构
Intercepting Filter类似于职责链模式
有两种实现
其中一种是Filter之间没有联系,全部Filter都存放在FilterChain中,由FilterChain来有序或无序地把把所有Filter调用一遍。没有用到链表这种数据结构。示例如下:
package com.ljn.filter.custom;
import java.util.ArrayList;
修改jboss端口
chicony
jboss
修改jboss端口
%JBOSS_HOME%\server\{服务实例名}\conf\bindingservice.beans\META-INF\bindings-jboss-beans.xml
中找到
<!-- The ports-default bindings are obtained by taking the base bindin
c++ 用类模版实现数组类
CrazyMizzz
C++
最近c++学到数组类,写了代码将他实现,基本具有vector类的功能
#include<iostream>
#include<string>
#include<cassert>
using namespace std;
template<class T>
class Array
{
public:
//构造函数
hadoop dfs.datanode.du.reserved 预留空间配置方法
daizj
hadoop 预留空间
对于datanode配置预留空间的方法 为:在hdfs-site.xml添加如下配置
<property>
<name>dfs.datanode.du.reserved</name>
<value>10737418240</value>
 
mysql远程访问的设置
dcj3sjt126com
mysql 防火墙
第一步: 激活网络设置 你需要编辑mysql配置文件my.cnf. 通常状况,my.cnf放置于在以下目录: /etc/mysql/my.cnf (Debian linux) /etc/my.cnf (Red Hat Linux/Fedora Linux) /var/db/mysql/my.cnf (FreeBSD) 然后用vi编辑my.cnf,修改内容从以下行: [mysqld] 你所需要: 1
ios 使用特定的popToViewController返回到相应的Controller
dcj3sjt126com
controller
1、取navigationCtroller中的Controllers
NSArray * ctrlArray = self.navigationController.viewControllers;
2、取出后,执行,
[self.navigationController popToViewController:[ctrlArray objectAtIndex:0] animated:YES
Linux正则表达式和通配符的区别
eksliang
正则表达式 通配符和正则表达式的区别 通配符
转载请出自出处:http://eksliang.iteye.com/blog/1976579
首先得明白二者是截然不同的
通配符只能用在shell命令中,用来处理字符串的的匹配。
判断一个命令是否为bash shell(linux 默认的shell)的内置命令
type -t commad
返回结果含义
file 表示为外部命令
alias 表示该
Ubuntu Mysql Install and CONF
gengzg
Install
http://www.navicat.com.cn/download/navicat-for-mysql
Step1: 下载Navicat ,网址:http://www.navicat.com/en/download/download.html
Step2:进入下载目录,解压压缩包:tar -zxvf navicat11_mysql_en.tar.gz
批处理,删除文件bat
huqiji
windows dos
@echo off
::演示:删除指定路径下指定天数之前(以文件名中包含的日期字符串为准)的文件。
::如果演示结果无误,把del前面的echo去掉,即可实现真正删除。
::本例假设文件名中包含的日期字符串(比如:bak-2009-12-25.log)
rem 指定待删除文件的存放路径
set SrcDir=C:/Test/BatHome
rem 指定天数
set DaysAgo=1
跨浏览器兼容的HTML5视频音频播放器
天梯梦
html5
HTML5的video和audio标签是用来在网页中加入视频和音频的标签,在支持html5的浏览器中不需要预先加载Adobe Flash浏览器插件就能轻松快速的播放视频和音频文件。而html5media.js可以在不支持html5的浏览器上使video和audio标签生效。 How to enable <video> and <audio> tags in
Bundle自定义数据传递
hm4123660
android Serializable 自定义数据传递 Bundle Parcelable
我们都知道Bundle可能过put****()方法添加各种基本类型的数据,Intent也可以通过putExtras(Bundle)将数据添加进去,然后通过startActivity()跳到下一下Activity的时候就把数据也传到下一个Activity了。如传递一个字符串到下一个Activity
把数据放到Intent
C#:异步编程和线程的使用(.NET 4.5 )
powertoolsteam
.net 线程 C# 异步编程
异步编程和线程处理是并发或并行编程非常重要的功能特征。为了实现异步编程,可使用线程也可以不用。将异步与线程同时讲,将有助于我们更好的理解它们的特征。
本文中涉及关键知识点
1. 异步编程
2. 线程的使用
3. 基于任务的异步模式
4. 并行编程
5. 总结
异步编程
什么是异步操作?异步操作是指某些操作能够独立运行,不依赖主流程或主其他处理流程。通常情况下,C#程序
spark 查看 job history 日志
Stark_Summer
日志 spark history job
SPARK_HOME/conf 下:
spark-defaults.conf 增加如下内容
spark.eventLog.enabled true spark.eventLog.dir hdfs://master:8020/var/log/spark spark.eventLog.compress true
spark-env.sh 增加如下内容
export SP
SSH框架搭建
wangxiukai2015eye
spring Hibernate struts
MyEclipse搭建SSH框架 Struts Spring Hibernate
1、new一个web project。
2、右键项目,为项目添加Struts支持。
选择Struts2 Core Libraries -<MyEclipes-Library>
点击Finish。src目录下多了struts