CGAL中2D三角剖分

@TOCCGAL 2D三角剖分

三角剖分概念

三角剖分是代数拓扑学里最基本的研究方法。
特性:(1)每一个面都是一个三角形(2)任何两个这样的曲边三角形,要么不相交,要么恰好相交于一条公共边

CGAL中三角剖分(2D)

cgal简单介绍:
计算几何算法库,是一个大型C + +库的几何数据结构和算法。如Delaunay三角网,网格生成,布尔运算的多边形,以及各种几何处理算法。
主要内容
三角剖分(看官方文档,参考地址:https://doc.cgal.org/latest/Manual/packages.html#PartTriangulationsAndDelaunayTriangulations)
三角测量和Delaunay三角测量(TriangulationsAndDelaunayTriangulations)
(1)首先了解CGAL三角剖分可以实现哪些功能,可以现在官网提供的demo
可以根据提供的点、线‘、面绘制三角剖分
(2)介绍三角剖分数据结构
三角数据结构概念(Triangulation Data Structure)
(1)三角剖分数据结构可以被视为面(Faces)和顶点(Vertices)的容器,保持它们之间的关联和邻接关系
(2)每个三角形面都可以访问它的三个关联顶点和它的三个相邻面。每个顶点都可以访问其一个入射面,并通过该面访问其入射面的循环列表。
如图:
在这里插入图片描述
面的三个顶点用0、1和2来索引。
面的邻居也用0、1和2进行索引,其索引方式与具有相同索引的顶点相反
根据句柄(Vertex_handle、Face_handle)访问顶点以及面
根据迭代器可以访问所有顶点、边、面
循环器访问与给定顶点相关的所有顶点、边和面
提供新添加一个顶点分割面或边、反转相邻的面等操作
三角剖分基础数据存储结构:Triangulation_data_structure_2
使用时需引入Triangulation_data_structure_2.h源文件
根据顶点(Triangulation_ds_vertex_base_2)以及面(Triangulation_ds_face_base_2)构建三角剖分存储结构(Triangulation_data_structure_2)
例如: CGAL::Triangulation_data_structure_2<Vb,Fb>
其中Vb: Triangulation_ds_vertex_base_2 Fb:Triangulation_ds_face_base_2
数据结构应用:
Triangulation_data_structure_2是Triangulation_2<Traits,Tds> 以及其他所有二维三角分剖的参数
Tds:Triangulation_data_structure_2
任何一种二维的三角剖分依赖于三角剖分数据结构
首先了解类声明以及具有哪些属性、方法
在这里插入图片描述

(3)介绍不同的二维三角剖分
每种三角剖分对应不同的类
在这里插入图片描述
CGAL中三角剖分参数
第一个参数:几何特征(geometric traits )(提供三角剖分的几何图元(点、线段和三角形)以及对这些对象的基本操作(谓词或构造)的类。)
第二个参数:三角剖分数据结构(triangulation data structure)(用于表示三角剖分的面和顶点的类型,以及用于访问面和顶点的附加类型(句柄、迭代器和循环器)。)
基本三角剖分的类以及属性、方法
在这里插入图片描述

基本三角剖分:简单说平面划分,有界面都是三角形,其中无限顶点没有有效的坐标、也没有几何谓词应用于它和无限面

	基本三角剖分(Triangulation_2)
	案例:
		#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>  几何特征
		#include <CGAL/Triangulation_2.h>   基本三角剖分结构
		//typedef 定义一种类型的别名
		typedef CGAL::Exact_predicates_inexact_constructions_kernel K;  
		typedef CGAL::Triangulation_2<K>         Triangulation;
		//不填写或者CGAL::Default   例如 typedef CGAL::Triangulation_2<K,CGAL::Default>        Triangulation;
		typedef Triangulation::Vertex_circulator Vertex_circulator;
		typedef Triangulation::Point             Point;
		//输入顶点			
        std::list<Point> points;
        points.push_back(Point(10,10));
        points.push_back(Point(-10,-10));
        points.push_back(Point(10,-10));
        points.push_back(Point(-10,10));
        //基本三角剖分对象
		  Triangulation t;
		  //插入顶点
		  t.insert(points.begin(),points. end());
		  //输出所有顶点、面个数
		  std::cout << t.number_of_vertices() << std::endl;
		 std::cout << t.number_of_faces() << std::endl;
		  //遍历所有面、顶点、边
    for (Triangulation::Vertex_iterator it = t.vertices_begin(); it != t.vertices_end();it++) {
        std::cout << it->point() << std::endl;
    }
    //有限顶点
    //t.finite_vertices_begin()
    //t.finite_faces_begin()
    //无限面的个数
    int infiniteCount = 0;
    for (Triangulation::Face_iterator it = t.faces_begin(); it != t.faces_end(); it++) {
        if (t.is_infinite(it)) {
            infiniteCount++;
            continue;
        }
        for (int i = 0; i < 3; i++) {
            //根据索引获取邻居,判断是否存在邻居
            Triangulation::Face_handle f = it->neighbor(i);
            //是不是有限面
            if (t.is_infinite(f)) {
                continue;
            }
            for (int j = 0; j < 3; j++) {
            //输出顶点坐标
            std::cout << f->vertex(j)->point() << std::endl;
            }
        }
    }   
    for (Triangulation::All_faces_iterator it = t.all_faces_begin(); it != t.all_faces_end(); it++) {
        if (t.is_infinite(it)) {
            infiniteCount++;
        }
    }
    std::cout << "无限个数:" << infiniteCount << std::endl;
    //读取无限顶点关联的顶点,取到三角剖分的凸包的顶点输出
    Vertex_circulator vc = t.incident_vertices(t.infinite_vertex()),
        done(vc);
    if (vc != nullptr) {
        do {
            std::cout << vc->point() << std::endl;
        } while (++vc != done);
    }

其他三角剖分继承基本三角剖分,使用方式与基本三角剖分相似,同时又有各自的特征
主要讲解 约束Delaunay三角剖分,因为后期使用了网格生成算法,依赖与约束Delaunay三角剖分
其他简单描述,有需求的可以看官方文档

	约束三角剖分(Constrained_triangulation_2)		
		受约束的三角剖分是一组点的三角剖分,它必须在其边中包括一组给定的连接这些点的折线。
		给定的折线称为限制并且三角测量中的相应边被称为约束边。
		对应的源文件  #include <CGAL/Delaunay_triangulation_2.h>
		例如:
		CGAL::Constrained_triangulation_2< Traits, Tds, Itag >
		Traits:几何特征
		Tds: 三角剖分数据结构或者默认
		Itag:	是交集标签,用于在处理约束交集的不同策略之间进行选择
		//该类有自己的的属性、方法
		 例如 插入、删除、查询约束边等		
	约束Delaunay三角剖分(Constrained_Delaunay_triangulation_2)		
		该类继承Constrained_triangulation_2
		空圆属性(也称为Delaunay属性):三角剖分的任何面的外接圆在其内部都不包含该集合的点。	
		对应的源文件  #include <CGAL/Constrained_Delaunay_triangulation_2.h>
	案例1:
		#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
		#include <CGAL/Constrained_Delaunay_triangulation_2.h>
		
		typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
		typedef CGAL::Exact_predicates_tag                               Itag;
		typedef CGAL::Constrained_Delaunay_triangulation_2<K, CGAL::Default, Itag> CDT;
		typedef CDT::Point Point;
		typedef CDT::Edge  Edge;
		//输入顶点			
	    std::list<Point> points;
	    points.push_back(Point(10, 10));
	    points.push_back(Point(5, 5));
	    points.push_back(Point(-10, -10));
	    points.push_back(Point(-5, -5));
	    points.push_back(Point(10, -10));
	    points.push_back(Point(-10, 10));
	    //基本三角剖分对象
	    CDT cdt;
	    //插入顶点
	    cdt.insert(points.begin(), points.end());
	    //插入约束边
	    std::list<Point> constraints;
	    constraints.push_back(Point(20, 20));
	    constraints.push_back(Point(-20, -20));
	    cdt.insert_constraint(constraints.begin(), constraints.end());
	    //是否有效
		assert(cdt.is_valid());
		int count = 0;
		for (const Edge& e : cdt.finite_edges())
	        //是不是约束边
			if (cdt.is_constrained(e))
				++count;
		std::cout << "The number of resulting constrained edges is  ";
		std::cout << count << std::endl;
	案例2(涉及网格生成):			
		#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>; //内部核心
		#include <CGAL/Constrained_Delaunay_triangulation_2.h>; //约束Delaunay三角剖分
		#include <CGAL/Delaunay_mesh_size_criteria_2.h>; //约束Delaunay三角剖分网格:网格划分标准。
		#include <CGAL/Delaunay_mesher_2.h>; //实现2D网格生成器,调用细化
		#include <CGAL/Delaunay_mesh_face_base_2.h>;
		#include <CGAL/Delaunay_mesh_vertex_base_2.h>;
		#include <CGAL/lloyd_optimize_mesh_2.h>;  //全局网格优化
		#include <CGAL/Projection_traits_xy_3.h> //三维在xy平面的投影
		//内部核心
		typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
		//根据几何特征创建投影信息
		typedef CGAL::Projection_traits_xy_3<K>  GT;
		//顶点
		//typedef CGAL::Triangulation_vertex_base_2<K> Vb;  //基本三角剖分的顶点基类
		//添加了两个功能,可访问double标记 对网格优化器很有用,可在修改网格时将网格密度保持在各处
		typedef CGAL::Delaunay_mesh_vertex_base_2<GT> Vb;			
		//面类  添加了两个函数,可访问布尔标记,该布尔标记指示面是否在网格划分域中
		typedef CGAL::Delaunay_mesh_face_base_2<GT> Fb;			
		// 函数模板通过<>里的参数进行实例化
		typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds; //三角剖分数据结构(指定顶点基类以及面基类)	
		//No_intersection_tag 如果不允许输入约束的交集,
		//Exact_predicates_tag 允许输入约束之间的交集,并在traits类提供确切谓词但交集点的近似构造时使用,
		//Exact_intersections_tag 允许输入约束之间的交集,并与精确的算术类型结合使用。
		typedef CGAL::Exact_predicates_tag Itag;			
		//约束Delaunay三角剖分,基础特性,类结构   
		typedef CGAL::Constrained_Delaunay_triangulation_2<GT, Tds, Itag> CDT;
		
		typedef CDT::Point Point;
		typedef CDT::Vertex_handle Vertex_handle;
		typedef CDT::Face_handle Face_handle;
		typedef CDT::Edge Edge;
		typedef CDT::Triangle Triangle;
		typedef CDT::Segment Segment;
		
		//CDT 必须是2D约束的Delaunay三角剖分。  三角形的形状标准
		typedef CGAL::Delaunay_mesh_size_criteria_2<CDT> Criteria;			
		//此类实现2D网格生成器  对CDT的类结构有要求
		typedef CGAL::Delaunay_mesher_2<CDT, Criteria> Mesher;			
		/**
		 * 生成约束边
		 */
		template <typename Iterator>
		static void GenerateConstraintLine(CDT &cdt, Iterator b, Iterator e)
		{
			Point p, q;
			Vertex_handle vh, wh;
			Iterator it = b;
			vh = cdt.insert(*it);
			p = *it;
			++it;
			for (; it != e; ++it){
				q = *it;
				if (p != q){
					wh = cdt.insert(*it);
					cdt.insert_constraint(vh, wh);
					vh = wh;
					p = q;
				}
				else {
					std::cout << "duplicate point: " << p << std::endl;
				}
			}
		}
					
		CDT cdt;	
		//转换成CGAL点对象
		std::list<Point> points;		
		//插入约束
		for(int i = 0; i < constraints->size(); i++)
		{
			points.clear();
			for(int j = 0; j < constraints->at(i).size(); j++)
			{
				points.push_back(Point(constraints->at(i).at(j).X, constraints->at(i).at(j).Y, constraints->at(i).at(j).Z));
			}
			if(points.size()>0){
				GenerateConstraintLine(cdt, points.begin(), points.end());
			}		
		}			
		//创建网格
		Mesher mesher(cdt);		
		//设置生成的三角网标准:角度、边长上限 
		mesher.set_criteria(Criteria(b, edgeLength));		
		//设置种子:确定哪些洞不参与生成三角网
		points.clear();
		for(int i = 0; i < seeds->size(); i++){
			points.push_back(Point(seeds->at(i).X, seeds->at(i).Y, seeds->at(i).Z));
		}
		if(points.size()>0){
			mesher.set_seeds(points.begin(), points.end(), false);
		}			
		//生成细化的网格
		mesher.refine_mesh();
		
	Delaunay三角剖分(Delaunay_triangulation_2)  没有细研究,有需要的可以看官方文档
		空圆属性(也称为Delaunay属性):三角剖分的任何面的外接圆在其内部都不包含该集合的点。
		对于没有超过三个点的共圆情况的点集,Delaunay三角剖分是唯一的,它是点的Voronoi图的对偶。
		对应的源文件  #include <CGAL/Delaunay_triangulation_2.h>		
					
	正则三角剖分(Regular_triangulation_2)	 没有细研究,有需要的可以看官方文档
		用于维护一组加权点的正则三角剖分
		对应的源文件  #include <CGAL/Regular_triangulation_2.h>	

(4)主要搭建环境,执行cgal中demo,更深层次的了解cgal中的三角剖分
我只需要运行cgal中的二维三角剖分,配置环境时只设置了cgal以及boost,qt
下载cgal最新版本,配置环境变量,
根据使用的编译工具以及下载的CGAL版本安装对应的boost以及qt
个人使用的是visualstudio2019,下载的最新版本CGAL5.5.1,boost_1_76_0-msvc-14.2-64
在项目中配置cgal以及boost环境
(1)配置项目属性页面,包含目录、库目录
在这里插入图片描述

(2)链接器
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
CGAL是计算几何算法库的缩写,它提供了许多用于处理和操作几何数据结构的算法和数据结构。在CGAL,3D三角剖分是一种用于将三维空间的点集划分为三角形面片的方法。根据引用所述,CGAL的3D三角剖分基于四面体结构。每个四面体包含四个顶点,其一个顶点是一个辅助顶点,称为无限顶点,用于处理无界单元。通过这种方式,每个面片对应两个四面体,同时可以处理凸包边界上的特殊情况。请注意,无限顶点没有具体的坐标意义,也没有几何谓词可以应用于它。你可以在引用提供的链接了解更多关于CGAL 3D三角剖分的详细信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [CGAL 二维三角剖分](https://blog.csdn.net/dayuhaitang1/article/details/128783294)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [CGAL 三维三角剖分](https://blog.csdn.net/dayuhaitang1/article/details/128881509)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值