通过CGAL将一个多边形剖分成Delaunay三角网

简介: 通过CGAL将一个多边形剖分成Delaunay三角网

通过CGAL将一个多边形剖分成Delaunay三角网

目录

1. 概述

对于平面上的点集,通过Delaunay三角剖分算法能够构建一个具有空圆特性和最大化最小角特性的三角网。空圆特性其实就是对于两个共边的三角形,任意一个三角形的外接圆中都不能包含有另一个三角形的顶点,这种形式的剖分产生的最小角最大。

更进一步的,可以给Delaunay三角网加入一些线段的约束条件,使得构建的Delaunay三角网能够利用这些线段。利用这个特性,可以将一个多边形剖分成Delaunay三角网,开源工具CGAL就正好提供了这个功能。

2. 实现

因为要显示三角网的效果,所以我在《使用QT绘制一个多边形》这篇博文提供的QT界面上进行修改,正好这篇文章提供的代码还实现了在QT中绘制多边形的功能。

关于网格化以及三角网剖分,在CGAL中提供了非常详尽繁复的解决方案,我这里选择了CGAL::refine_Delaunay_mesh_2这个接口,这个接口能够将多边形区域构建成一个Delaunay三角网,如果当前的存在三角形不满足Delaunay,就会在其中补充一些点来满足Delaunay的相关特性。主要的实现代码如下(具体代码见文章最后):

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <CGAL/Delaunay_mesher_2.h>
#include <CGAL/Delaunay_mesh_face_base_2.h>
#include <CGAL/Delaunay_mesh_size_criteria_2.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Triangulation_vertex_base_2<K> Vb;
typedef CGAL::Delaunay_mesh_face_base_2<K> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds;
typedef CGAL::Constrained_Delaunay_triangulation_2<K, Tds> CDT;
typedef CGAL::Delaunay_mesh_size_criteria_2<CDT> Criteria;
typedef CDT::Vertex_handle Vertex_handle;
typedef CDT::Point Point;
//三角化
void GraphicsPainter::Triangulate()
{
    //找到边界上所有的像素点
    vector<Vector2d> ROIBoundPointList;
    CalBoundPoint(ROIBoundPointList);
    CDT cdt;
    vector<Vertex_handle> vertexList;
    cout<<ROIBoundPointList.size()<<endl;
//    for(int i = 0; i<pointList.size(); i++)
//    {
//        vertexList.push_back(cdt.insert(Point(pointList[i].x(), pointList[i].y() )));
//    }
    for(int i = 0; i<ROIBoundPointList.size(); i++)
    {
        vertexList.push_back(cdt.insert(Point(ROIBoundPointList[i].x, ROIBoundPointList[i].y )));
    }
    for(unsigned int i =0;i<vertexList.size()-1;i++)
    {
        cdt.insert_constraint(vertexList[i],vertexList[i+1]);
    }
    //cdt.insert_constraint(vertexList[vertexList.size()-1],vertexList[0]);
    std::cout << "Number of vertices: " << cdt.number_of_vertices() <<std::endl;
    std::cout << "Meshing the triangulation..." << std::endl;
    CGAL::refine_Delaunay_mesh_2(cdt, Criteria());
    std::cout << "Number of vertices: " << cdt.number_of_vertices() <<std::endl;
    CDT::Face_iterator fit;
    for (fit = cdt.faces_begin(); fit!= cdt.faces_end(); ++fit)
    {
        QVector<QPointF> triPoint;
        triPoint.push_back(QPointF(fit->vertex(0)->point().x(), fit->vertex(0)->point().y()));
        triPoint.push_back(QPointF(fit->vertex(1)->point().x(), fit->vertex(1)->point().y()));
        triPoint.push_back(QPointF(fit->vertex(2)->point().x(), fit->vertex(2)->point().y()));
        QPolygonF tri(triPoint);
        triList.push_back(tri);
    }
    bTri = true;
    update();
}

3. 结果

在QT界面上绘制一个多边形,只用多边形上的点,最后的三角网格效果:

通过这篇博文《矢量线的一种栅格化算法》提供的栅格化算法,可以将一个多边形栅格化,这样就可以得到一个栅格多边形,通过这个算法网格化,最后的效果:

可以发现这种方式会在内部新添加一些点,来满足Delaunay特性。并且会形成边界密集,中间稀疏的网格效果。在一些图形、图像处理中,会用到这种自适应网格(Adaptive Mesh)。

4. 参考

  1. Delaunay三角剖分学习笔记

实现代码

分类: 计算几何

标签: 三角剖分 , 三角网 , Delaunay , CGAL


相关文章
|
C++
UE4/5中DataTable数据表的使用
UE4/5中DataTable数据表的使用
1393 1
UE4/5中DataTable数据表的使用
|
10月前
|
人工智能 IDE 程序员
GitHub Copilot 免费了!程序员们的福音来了!
《GitHub Copilot 免费了!程序员们的福音来了!》 近日,GitHub 宣布其 AI 编程助手 GitHub Copilot 现在可以免费使用。曾经每月需支付 10 美元订阅费的 Copilot,现在向所有人开放免费版本,这对个人开发者、初学者和小型团队来说是个大好消息。免费版支持 GPT 和 Claude 模型,并提供每月 2000 次代码补全和 50 条聊天消息等核心功能。用户只需注册或登录 GitHub 账户,在 VS Code 中安装扩展并激活免费版即可使用。此外,Visual Studio Code 也完全免费,进一步降低了开发门槛。 除了
11090 7
GitHub Copilot 免费了!程序员们的福音来了!
|
9月前
|
弹性计算 Ubuntu Linux
阿里云服务器一键安装Docker社区版教程,基于系统运维管理OOS
阿里云服务器一键安装Docker社区版教程,基于系统运维管理OOS自动化部署。支持Ubuntu 22.04/20.04、CentOS 7.7-7.9及Alibaba Cloud Linux 3.2104 LTS。前提条件:ECS实例需运行中且有公网。步骤:选择Docker扩展并安装,验证成功通过命令`docker -v`查看版本号。
654 79
|
6月前
|
数据处理 虚拟化 图形学
ESXi 8.0U3e 免费版发布,含官方免费许可证 (序列号 SN Key)
ESXi 8.0U3e 免费版发布,含官方免费许可证 (序列号 SN Key)
1622 5
|
消息中间件 Dubbo 应用服务中间件
微服务调用中TraceId是如何传递的?
由于网络原因,我暂时无法解析提供的网页链接。请检查链接是否有效,或稍后再试。如果您有其他问题或需要帮助,请随时告诉我。
微服务调用中TraceId是如何传递的?
|
Linux Perl
Linux进行文件字符串替换
【8月更文挑战第5天】Linux进行文件字符串替换
973 3
|
Rust JavaScript Java
简单对比Java、Python、Go、Rust等常见语言计算斐波拉契数的性能
简单对比Java、Python、Go、Rust等常见语言计算斐波拉契数的性能
291 0
|
物联网 C# C语言
物联网开发中C、C++和C#哪个更好用
在物联网(IoT)开发中,C、C++和C#各有优缺点,适用场景不同。C语言性能高、资源占用低,适合内存和计算能力有限的嵌入式系统,但开发复杂度高,易出错。C++支持面向对象编程,性能优秀,适用于复杂应用,但学习曲线陡峭,编译时间长。C#易于学习,与.NET框架结合紧密,适合快速开发Windows应用,但性能略低,平台支持有限。选择语言需根据具体项目需求、复杂性和团队技术栈综合考虑。
|
算法 编译器 程序员
成为C++重载大师:深入理解重载决议
成为C++重载大师:深入理解重载决议
218 0
JM
|
算法 数据可视化 C++
修改 UE5 中的渲染管线
前言本文重点介绍如何修改 UE5 中的渲染管线,要修改渲染管线有一些前置知识需要理解,因此笔者会先简单介绍下渲染管线的概念以及当前主流的渲染管线的实现思路,为后面在 UE5 中自定义渲染管线做铺垫;要注意本文默认渲染管线即是光栅化渲染管线(不考虑光线追踪),同时也不会介绍太多管线的实现细节和当下流行的优化版本,对渲染管线实现细节感兴趣的可以自行查阅相关资料。渲染管线 Rendering Pipel
JM
3886 0
修改 UE5 中的渲染管线