如何使用Matlab进行三角剖分(自定义函数实现delaunayTriangulation 使用Bowyer-Watson 算法)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录

前言

一、Delaunay三角形

二、使用步骤

1.Bowyer-Watson算法

2.算法步骤

三、动画演示

四、核心代码

五、对比matlab自带函数和我们的算法:

总结


前言

前一篇文章《Matlab三角剖分插值问题分析(二)_matlab 空间面的三角剖分-CSDN博客》,讲的是使用剖分后的结果进行不规则的散点插值,这篇文章主要是讲如何形成剖分


一、Delaunay三角形

给定平面上的一组点集 P,Delaunay 三角剖分是将点集划分成若干个不重叠的三角形,使得任何一个三角形的外接圆不包含其他点。

有很多博客详细描述了定义和性质,我这边就不详细描述了。

Delaunay三角剖分——BW算法-CSDN博客

Delaunay三角剖分算法_delaunay 三角剖分算法-CSDN博客

二、使用步骤

1.Bowyer-Watson算法

Bowyer-Watson算法是一种增量算法。它的工作原理是将点一次一个地,添加到所有点的子集的Delaunay三角剖分中。每次插入新点后,任何外接圆包含新点的三角形都被删除,留下一个星形多边形孔,然后使用新点重新三角化。

2.算法步骤

Bowyer-Watson算法是一种用于构建Delaunay三角剖分的增量算法。该算法通过逐步添加点并调整三角剖分来保持Delaunay性质。以下是Bowyer-Watson算法的基本步骤

  1. 初始三角剖分

    • 创建一个足够大的超级三角形,覆盖所有要处理的点。
    • 该超级三角形的顶点应位于所有点之外,以确保初始三角剖分包含所有点。
  2. 逐点插入

    • 对每个点进行以下操作:
      1. 找到所有包含该点的三角形(即该点在这些三角形的外接圆内)。
      2. 移除这些三角形。
      3. 创建新三角形,将新点与移除三角形的相邻顶点连接。
  3. 删除超级三角形相关的三角形

    • 移除所有包含超级三角形顶点的三角形,得到最终的Delaunay三角剖分。

下是Bowyer-Watson算法的伪代码引自 Delaunay三角剖分——BW算法-CSDN博客

 1 function BowyerWatson (pointList)
 2     // pointList is a set of coordinates defining the points to be triangulated
 3     triangulation := empty triangle mesh data structure
 4     add super-triangle to triangulation // must be large enough to completely contain all the points in pointList
 5     for each point in pointList do // add all the points one at a time to the triangulation
 6         badTriangles := empty set
 7         for each triangle in triangulation do // first find all the triangles that are no longer valid due to the insertion 对应第2步:新插入点是否在三角形外接圆中
 8             if point is inside circumcircle of triangle
 9                 add triangle to badTriangles
10         polygon := empty set
11         for each triangle in badTriangles do // find the boundary of the polygonal hole 比如图中的ABCD
12             for each edge in triangle do
13                 if edge is not shared by any other triangles in badTriangles
14                     add edge to polygon
15         for each triangle in badTriangles do // remove them from the data structure
16             remove triangle from triangulation
17         for each edge in polygon do // re-triangulate the polygonal hole
18             newTri := form a triangle from edge to point
19             add newTri to triangulation
20     for each triangle in triangulation // done inserting points, now clean up 插完所有点了,现在清理掉外围的三角形,如下图中的蓝色三角形之外的三角形。
21         if triangle contains a vertex from original super-triangle
22             remove triangle from triangulation
23     return triangulation

三、动画演示

如果对原理理解困难,youtube有个动画演示,讲的不错,我这边截下来分解动作再说说

https://www.youtube.com/watch?v=GctAunEuHt4&t=1s

要找上面四个点的德劳内三角剖分

先构造一个超级三角形,把所有点都包含在内

选择一个点,在你所有的三角形集内找一个三角形,它的外接圆包含我们这个点,当下只有超级三角满足

这不是我们想要的结果(显然超级三角形不是得劳内三角形,不满足只含三个点)我们把此点和三角形的三个顶点都连接上,形成新的三角形,都加到集内

现在处理下面的两个点,在三角形集内找到所有(外接圆)包含这个点的三角形

把这两个三角形处理,删除掉他们的公共边,形成“星形多边形”

同时这个黄点也要连接上所有的顶点,形成的新的四个小三角形也要加到集内

右侧这个点也要相同处理,有两个三角形的外接圆包含它

删掉公共边,形成星形多边形,把这个点和多边形的顶点连接起来

最后是最上面的点,也做相同的处理。

删掉 超三角形的边和顶点,那么那些连接线也得删掉,剩下就是我们要的得劳内三角剖分了

四、核心代码

triangles{1} = super_triangle;

for i = 1:length(points)
    point = points(i);
    triangles = AddPointToMesh(point, triangles);    
end

triangles = RemoveSuperTriangle(triangles, super_triangle);

mesh = triangles;

其中 AddpointToMesh

function good_triangles = AddPointToMesh(point,triangles)
    global Edge Circum_cricle Triangle
    k1 = 1;k2 =1;
    for i = 1:length(triangles)
        triangle = triangles{i};
        
%         plot_triangle(triangle);
%         plot_circumcircle(triangle);
        
        if IsInCircumCircle(point,triangle)
            edges{k1} = triangle.edges(1);
            edges{k1+1} = triangle.edges(2);
            edges{k1+2} = triangle.edges(3);
            k1 = k1+3;
        else
            good_triangles{k2} = triangle;
            k2 = k2+1;
        end
    end
    
    edges = GetUniqueEdges(edges);
    
    for i  = 1:length(edges)
        edge = edges{i};        
        e1 = Edge;        e2 = Edge;        e3 = Edge;        
        e1.points(1) = edge.points(1);
        e1.points(2) = edge.points(2);
        e2.points(1) = edge.points(2);
        e2.points(2) = point;
        e3.points(1) = point;
        e3.points(2) = edge.points(1);
        triangle = Triangle;
        triangle.edges(1) = e1;
        triangle.edges(2) = e2;
        triangle.edges(3) = e3;
        
        good_triangles{k2} = triangle;
%         plot_triangle(triangle);
        k2 = k2+ 1;
    end
    
end

 RemoveSuperTriangle

function mesh_triangles = RemoveSuperTriangle(triangles,super_triangle)
    super_tri_p1 = super_triangle.edges(1).points(1);
    super_tri_p2 = super_triangle.edges(2).points(1);
    super_tri_p3 = super_triangle.edges(3).points(1);
    k = 1;
    for i = 1:length(triangles)
        triangle = triangles{i};
        p1 = triangle.edges(1).points(1);
        p2 = triangle.edges(2).points(1);
        p3 = triangle.edges(3).points(1);
        
        if ~ ( is_point_same(p1,super_tri_p1) || is_point_same(p1 ,super_tri_p2) || is_point_same(p1, super_tri_p3) || ...
                    is_point_same(p2 ,super_tri_p1) || is_point_same(p2,super_tri_p2) || is_point_same(p2,super_tri_p3) || ...
                    is_point_same(p3, super_tri_p1) || is_point_same(p3,super_tri_p2) || is_point_same(p3, super_tri_p3))
            mesh_triangles{k} = triangle;
            k = k +1;
        end
    end
end

五、对比matlab自带函数和我们的算法:

        对比如下:自带函数

T = delaunay(x,y);
% tri = delaunayTriangulation(T, x, y ,z);

trisurf(T,x,y,z)

使用我们自己的

已经完全对上了

总结

完整的包可以从这里下载:

自定义函数实现delaunayTriangulation使用Bowyer-Watson算法资源-CSDN文库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/633281.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

巨某量引擎后台登录实战笔记 | Playwright自动化框架

前言 本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 入正题看看滑块是怎么个事…

CasaOS系统玩客云安装内网穿透工具实现无公网IP远程访问

文章目录 前言1. CasaOS系统介绍2. 内网穿透安装3. 创建远程连接公网地址4. 创建固定公网地址远程访问 前言 2月底,玩客云APP正式停止运营,不再提供上传、云添加功能。3月初,有用户进行了测试,局域网内的各种服务还能继续使用&am…

Ai自动贴图直播项目的趋势,智享自动直播GMV增加工具

在当今社会,直播行业正在悄然地改变着人们的生活方式。无论是在闲暇时光中放松身心,还是在临睡前享受休闲娱乐,观众们越来越习惯于通过刷短视频或者观看直播来消遣自己。根据统计数据显示,到2023年全球将有超过10.74亿网民&#x…

Android 12系统源码_多窗口模式(二)系统实现分屏的功能原理

前言 上一篇我们具体分析了系统处于多窗口模式下,Android应用和多窗口模式相关方法的调用顺序,对于应用如何适配多窗口模式有了一个初步的认识,本篇文章我们将会结合Android12系统源码,具体来梳理一下系统是如何触发多窗口分屏模…

2024全新爆款好物推荐,618必买数码好物清单吐血整理!

​距离618购物狂欢节越来越近了,有很多日常价格不菲的产品在这次活动期间都会进行促销活动,尤其是数码类产品,加上618的优惠活动更有吸引力了。不过面对大促的热潮我们消费者在选购商品的同时还是要擦亮眼睛,避免买到质量不好的商…

[Redis]基本全局命令

Redis存储方式介绍 在 Redis 中数据是以键值对的凡事存储的,键(Key)和值(Value)是基本的数据存储单元。以下是对 Redis 键值对的详细讲解: 键(Key): 类型:…

英伟达:AI之火还在燃烧!

昨晚,全球市场屏息以待的一家公司财报终于发布了,没有超出大家预期的是,他还是超预期了。 大家当然都知道我们要说的是——英伟达! 如今,全球大模型之Z激Z正酣,AI芯片装备竞赛需求猛烈,作为AI…

OPPO Reno12 系列正式发布,仅2699元起售

5月23日,OPPO发布科技潮品 Reno12 系列,包含 Reno12 与 Reno12 Pro,以超美小直屏设计,以及行业首发的新科技,引领全新潮流方向。 据「TMT星球」了解,首次亮相的全新配色 Reno12 「千禧银」与Reno12 Pro的「…

spring常用知识点

1、拦截器和过滤器区别 1. 原理不同: 拦截器是基于java的反射机制,而过滤器采用责任链模式是基于函数回调的。 2. 使用范围不同: 过滤器Filter的使用依赖于Tomcat等容器,导致它只能在web程序中使用 拦截器是一个Sping组件&am…

爆火!开源多模态大模型在手机端进行本地部署!

节前,我们组织了一场算法岗技术&面试讨论会,邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。 针对大模型& AIGC 技术趋势、大模型& AIGC 落地项目经验分享、新手如何入门算法岗、该如何准备面试攻略、面试常考点等热门话题进行了…

Rust Tarui 中的 Scrcpy 客户端,旨在提供控制安卓设备的鼠标和按键映射,类似于游戏模拟器。

Scrcpy-mask 为了实现电脑控制安卓设备,本人使用 Tarui Vue 3 Rust 开发了一款跨平台桌面客户端。该客户端能够提供可视化的鼠标和键盘按键映射配置。通过按键映射实现了实现类似安卓模拟器的多点触控操作,具有毫秒级响应速度。该工具可广泛用于电脑控…

【算法】二分算法——寻找峰值

题解:寻找峰值(二分算法) 目录 1.题目2.暴力求解3.二分算法4.总结 1.题目 题目链接:LINK 2.暴力求解 暴力求解的思路很简单,这个数组的形状无非就三种: 一直上升下降(这里包含先下降后上升)先升后降 总结一下规律&#xff1…

智能AI愈发强大,企业如何防范AI网络钓鱼攻击

随着AI技术的快速发展,如ChatGPT等智能化工具在各个领域得到了广泛应用。然而,这些工具的普及也给网络安全带来了新的挑战。AI模型的自然语言生成功能使得网络钓鱼攻击更加智能化和隐蔽化,攻击者能够利用AI技术生成高度逼真的欺骗性邮件和其他…

银河麒麟操作系统下使用QT连接TiDB数据库开发步骤

目标:实现项目软件+硬件都运行在国产化操作系统平台上。 方法:在虚拟机中安装麒麟系统V10Sp1+Qt5.14.2+MySql8.0+TiDB软件,编译MySql驱动,测试连接TiDB数据库项目。 步骤: 1、使用虚拟机软件VMWare安装银河麒麟操作系统。 2、在银河麒麟系统上安装QT5.14.2软件。 3、…

2024年5月20日优雅草蜻蜓API大数据服务中心v2.0.4更新

v2.0.4更新 v2.0.4更新 2024年5月20日优雅草蜻蜓API大数据服务中心v2.0.4更新-增加ai绘画接口增加淘宝联想词接口底部增加联系方式 更新日志 底部增加联系方式 增加ai绘画接口 增加淘宝联想词接口 增加用户中心充值提示 用户中心内页颜色改版完成 截图 部分具体更新接口信…

算法练习第23天|131.分割回文串、93.复原IP地址

131.分割回文串 131. 分割回文串 - 力扣(LeetCode)https://leetcode.cn/problems/palindrome-partitioning/description/ 题目描述: 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有…

23-LINUX--TCP连接状态

一.TCP服务的特点 传输层协议主要有两个:TCP 协议和 UDP协议。TCP 协议相对于UDP协议的特点是:面向连接、字节流和可靠传输。 使用TCP协议通信的双方必须先建立连接,然后才能开始数据的读写。双方都必须为该连接分配必要的内核资源&a…

STM32_ADC

1、ADC简介 ADC,即Analog-Digital Converter,模拟-数字转换器。 ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁。 12位逐次逼近型ADC,1us转换时间。 输入电压范围:0~3.3…

AHPPEBot:基于表型和姿态估计的自主番茄采摘机器人

论文:AHPPEBot: Autonomous Robot for Tomato Harvesting based on Phenotyping and Pose Estimation 作者:Xingxu Li, Nan Ma, Yiheng Han, Shun Yang, Siyi Zheng 收录:ICRA2024 编辑:东岸因为一点人工一点智能 AHPPEBot&am…

如何将Windows PC变成Wi-Fi热点?这里提供详细步骤

序言 Windows 10和Windows 11都有内置功能,可以将你的笔记本电脑(或台式机)变成无线热点,允许其他设备连接到它并共享你的互联网连接。以下是操作指南。 由于Windows中隐藏的虚拟Wi-Fi适配器功能,你甚至可以在连接到另一个Wi-Fi网络或无线路由器时创建Wi-Fi热点,通过另…