如何使用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 triangulated3     triangulation := empty triangle mesh data structure4     add super-triangle to triangulation // must be large enough to completely contain all the points in pointList5     for each point in pointList do // add all the points one at a time to the triangulation6         badTriangles := empty set7         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 triangle9                 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);    
endtriangles = RemoveSuperTriangle(triangles, super_triangle);mesh = triangles;

其中 AddpointToMesh

function good_triangles = AddPointToMesh(point,triangles)global Edge Circum_cricle Trianglek1 = 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;elsegood_triangles{k2} = triangle;k2 = k2+1;endendedges = 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;endend

 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;endend
end

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

        对比如下:自带函数

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

使用我们自己的

已经完全对上了

总结

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谷歌开源项目BERT源码解读与应用实例

数据及代码见文末 基于BERT的中文情感分析实战:基于BERT的中文情感分析实战-CSDN博客 基于BERT的中文命名实体识别识别实战:基于BERT的中文命名实体识别识别实战-CSDN博客 1.项目配置文件 GLUE/BERT_BASE_DIR是项目的预训练权重,预训练权重主要包含3个部分:参数配置文件…

打气球小游戏

1.气球往上飘 我们声明两个符号常量来作为窗体的长和宽,接着就是常规操作 #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 600#include<easyx.h> #include<stdio.h> int main() {initgraph(WINDOW_WIDTH, WINDOW_HEIGHT);setbkcolor(WHITE);cleardevice();get…

python+selenium - UI自动框架之封装浏览器引擎driver方法

在做兼容性测试的适合&#xff0c;可以运行指定的浏览器&#xff08;IE,Chrome,Edge&#xff09; 目录文件&#xff1a; from selenium import webdriver from urllib3.exceptions import ProtocolError from common.log import *def getDriver():# if browserType is None:br…

模拟面试题

1.装箱和拆箱是指什么&#xff1f; 装箱——把栈中内容迁移到堆中去&#xff08;值转引用&#xff09; 拆箱——把堆中内容迁移到栈中去&#xff08;引用转值&#xff09; 2.值和引用类型在变量赋值时的区别是什么&#xff1f; 值类型&#xff1a;赋值时复制数据本身&a…

Gitee在已有项目基础上创建仓库中遇到的问题和解决

问题一&#xff1a;fatal: remote origin already exists 解释&#xff1a;当前仓库添加了一个名为"origin"的远程仓库配置&#xff0c;此时输入 git remote add origin https://xxx就会提示上面的内容。 解决方案1:移除旧的origin git remote remove origin 解决方案…

C++——mapset红黑树

目录 一补充知识 1关联式容器 2键值对 二set 1set的介绍 2set的使用 三map 1map的说明 2map的使用 四容器在oj中的使用 五AVL树 1概念 2插入 3AVL的旋转 3.1右单旋 3.2左单旋 3.3左右双旋 3.4右左双旋 4判断AVL树是否平衡 完整源代码 六红黑树 1概念 2性…

紫光展锐突破创新终端品类,搭载展锐芯的全球首款二合一5G云电脑正式发布

近日&#xff0c;搭载紫光展锐5G芯片T760的中兴云电脑逍遥系列正式发布&#xff0c;亮点&#xff1a; 全球首款二合一5G云电脑&#xff0c;支持本地/云端双模式&#xff0c;一键切换&#xff0c;用户可同时享有Android平板和Windows云电脑两种形态&#xff1b;支持5G蜂窝网络&…

C++相关概念和易错语法(13)(string的模拟实现)

string由于存在字符串和单字符的概念&#xff0c;使得它的一些接口&#xff0c;实现要比vector多一些。本质上来看string的实现是在顺序表的基础上加入串相关的操作。下面我会分享如何模拟实现string&#xff0c;这可以进一步提高我们对string的熟练程度。 1.构造函数、拷贝构…

附代码:策略常用-正余弦优化算法

正余弦优化算法作为群智能优化算法的一种, 正弦余弦算法 (sine cosine algorithm, SCA) 是 2016 年由 Mirjalili 提出的一种新型仿自然优化算法, 通过创建多个随机候选解, 利用正余弦函数的数学性质来平衡算法在搜系过程中的全局探索和局部开发能力。该算法具有结构简单、参数少…

docker三种自定义网络(虚拟网络) overlay实现原理

docker提供了三种自定义网络驱动&#xff1a;bridge、overlay、macvlan。 bridge驱动类似默认的bridge网络模式。 overlay和macvlan是用于创建跨主机网络。 支持自定义网段、网关&#xff0c;docker network create --subnet 172.77.0.0/24 --gateway 172.77.0.1 my_n…

PPT大珩助手新功能-生成迷宫

大珩助手是一款功能丰富的办公软件插件&#xff0c;它主要分为两个版本&#xff1a;PPT大珩助手和Word大珩助手。这两个版本都旨在提高用户在处理演示文稿和文档时的效率。 PPT大珩助手 这是一款专门为Microsoft PowerPoint设计的插件。它提供了多种功能&#xff0c;例如素材…

盲人社区生活支持体系:织就一张温暖的网

在当今社会&#xff0c;构建一个全面、包容的盲人社区生活支持体系成为了推动社会进步、保障残障人士权益的重要议题。随着科技的不断革新&#xff0c;一款名为“蝙蝠避障”的辅助软件走进了盲人的日常生活&#xff0c;它如同一位无形的向导&#xff0c;通过实时避障与拍照识别…

element DatePicker 日期选择器设置禁用未来日期,时间范围为60天

需要用到 DatePicker 里面的 picker-options 方法 disabledDate onPick方法 <el-date-pickerv-model"form.xxxx"type"daterange"value-format"yyyy-MM-dd":clearable"false":picker-options"pickerOptions"start-placeho…

运行Android项目时,提示错误: 程序包javax.annotation.processing不存在

今天在运行项目时提示错误: 错误: 程序包javax.annotation.processing不存在 import javax.annotation.processing.Generated; 最后是修改了Android Studio的JDK的路径修改为你安装的JDK路径&#xff0c;完成的修复&#xff1a;

5.23 Linux中超时检测方式+模拟面试

1.IO多路复用的原理&#xff1f; IO多路复用使得一个或少量线程资源处理多个连接的IO事件的技术。对于要处理的多个阻塞的IO操作&#xff0c;建立集合并存储它们的文件描述符&#xff0c;利用单个阻塞函数去监控集合中文件描述符事件到达的情况&#xff0c;&#xff08;如果到…

cPanel中如何移除之前添加的域名

我这边想要移除我之前绑定到主机的域名&#xff0c;但是不知道如何在主机上面进行移除&#xff0c;由于我使用的Hostease的Linux虚拟主机产品默认带普通用户权限的cPanel面板&#xff0c;但是不知道如何在cPanel上操作移除域名&#xff0c;因为也是对于Hostease主机产品不是很了…

Linux磁盘高级操作

RAID RAID存储系统是一种数据存储虚拟化技术&#xff0c;它将多个物理磁盘驱动器组合成一个或多个逻辑单元&#xff0c;以提供数据冗余和/或提高性能。 1. RAID 0 无奇偶校验与冗余&#xff08;磁盘容错&#xff09;的条带存储&#xff08;带区卷/条带卷&#xff09; 由两块…

基于windows通过kind部署轻量级便携式k8s集群

感谢老师的视频教程&#xff1a; 基于windows通过kind部署轻量级便携式k8s集群 wsl windows下的linux wsl --set-default-version 2 wsl --help wsl --list --online wsl --install -d Ubuntu wsl -l -v &#xff08;看看版本是不是2&#xff0c;否则docker那边识别不到&…

从零开始:在线教育系统源码与知识付费小程序开发指南

开发一个功能完善的在线教育系统和知识付费小程序并不是一件简单的事情。今天&#xff0c;小编将从零开始&#xff0c;详细介绍如何开发在线教育系统和知识付费小程序。 一、需求分析与系统设计 在开始编写代码之前&#xff0c;首先需要进行需求分析和系统设计。这一步非常关键…

汽车摄像头智能画质增强解决方案,高品质车载视觉系统

在数字化与智能化浪潮的推动下&#xff0c;汽车行业正经历着一场前所未有的技术革命。其中&#xff0c;车载摄像头作为智能驾驶与安防监控的核心部件&#xff0c;其画质的高低直接关系到行车安全与驾驶体验。美摄科技&#xff0c;作为行业领先的智能图像技术解决方案提供商&…