平面剖分三角形Delaunay算法实现

前端版实现:https://github.com/ccinos/TriangleMesh

Delaunay2D.cs下载

void Triangulate() {/* 基于Bowyer-Watson算法原理* 通过所有顶点和现有三角形进行判断, 对包含该点的三角形进行拆分* 首先构建初始的三角形,包含全部点在内(最后会删除)* * 遍历所有顶点 {*    遍历所有现有三角形 {*        首先判断是否 [顶点] 在 [三角形] 内, 如果不在则跳过*        [顶点] 和 [三角形] 的3条边,生成新的3个三角形,加入现有三角形集合中*    }* }*/#region 构建初始三角形,可以包含住所有的点float minX = Vertices[0].Position.x;float minY = Vertices[0].Position.y;float maxX = minX;float maxY = minY;foreach (var vertex in Vertices) {if (vertex.Position.x < minX) minX = vertex.Position.x;if (vertex.Position.x > maxX) maxX = vertex.Position.x;if (vertex.Position.y < minY) minY = vertex.Position.y;if (vertex.Position.y > maxY) maxY = vertex.Position.y;}float dx = maxX - minX;float dy = maxY - minY;float deltaMax = Mathf.Max(dx, dy) * 2;Vertex p1 = new Vertex(new Vector2(minX - 1, minY - 1));Vertex p2 = new Vertex(new Vector2(minX - 1, maxY + deltaMax));Vertex p3 = new Vertex(new Vector2(maxX + deltaMax, minY - 1));Triangles.Add(new Triangle(p1, p2, p3));#endregion#region 通过顶点对三角形进行拆分//遍历所有顶点foreach (var vertex in Vertices) {List<Edge> polygon = new List<Edge>();//遍历所有现有三角形foreach (var t in Triangles) {if (t.CircumCircleContains(vertex.Position)) {//如果包含该点//标记删除t.IsBad = true;//记录下三条边polygon.Add(new Edge(t.A, t.B));polygon.Add(new Edge(t.B, t.C));polygon.Add(new Edge(t.C, t.A));}}//删除标记的三角形Triangles.RemoveAll((Triangle t) => t.IsBad);//删除近似的边for (int i = 0; i < polygon.Count; i++) {for (int j = i + 1; j < polygon.Count; j++) {if (Edge.AlmostEqual(polygon[i], polygon[j])) {polygon[i].IsBad = true;polygon[j].IsBad = true;}}}polygon.RemoveAll((Edge e) => e.IsBad);//通过点和边构建新的三角形,加入到现有三角形集合中foreach (var edge in polygon) {Triangles.Add(new Triangle(edge.U, edge.V, vertex));}}//删除所有包含初始点的三角形Triangles.RemoveAll((Triangle t) => t.ContainsVertex(p1.Position) || t.ContainsVertex(p2.Position) || t.ContainsVertex(p3.Position));#endregion#region 提取边信息HashSet<Edge> edgeSet = new HashSet<Edge>();foreach (var t in Triangles) {var ab = new Edge(t.A, t.B);var bc = new Edge(t.B, t.C);var ca = new Edge(t.C, t.A);if (edgeSet.Add(ab)) {Edges.Add(ab);}if (edgeSet.Add(bc)) {Edges.Add(bc);}if (edgeSet.Add(ca)) {Edges.Add(ca);}}#endregion}

扩展立体空间中,三角形剖分变为四面体剖分:

Delaunay3D.cs下载

  void Triangulate() {/* 基于Bowyer-Watson算法原理* 通过所有顶点和现有四面体进行判断, 对包含该点的四面体进行拆分* 首先构建初始的四面体,包含全部点在内,并在最后删除* * 遍历所有顶点 {*    遍历所有现有四面体 {*        首先判断是否 [顶点] 在 [四面体] 内, 如果不在则跳过*        [顶点] 和 [四面体] 的四个三角形,生成新的四个四面体,加入现有四面体集合中*    }* }* * 通过以上步骤可以得到所有点相关的四面体* 将这些四面体的三角形信息拿出来即可*/#region 构建初始四面体,可以包含住所有点的四面体float minX = Vertices[0].Position.x;float minY = Vertices[0].Position.y;float minZ = Vertices[0].Position.z;float maxX = minX;float maxY = minY;float maxZ = minZ;//1.计算顶点中最大和最小的坐标 x,y,z => minX,minY,minZ,maxX,maxY,maxZforeach (var vertex in Vertices) {if (vertex.Position.x < minX) minX = vertex.Position.x;if (vertex.Position.x > maxX) maxX = vertex.Position.x;if (vertex.Position.y < minY) minY = vertex.Position.y;if (vertex.Position.y > maxY) maxY = vertex.Position.y;if (vertex.Position.z < minZ) minZ = vertex.Position.z;if (vertex.Position.z > maxZ) maxZ = vertex.Position.z;}//2.计算坐标差 dx,dy,dzfloat dx = maxX - minX;float dy = maxY - minY;float dz = maxZ - minZ;float deltaMax = Mathf.Max(dx, dy, dz) * 2;Vertex p1 = new Vertex(new Vector3(minX - 1, minY - 1, minZ - 1));Vertex p2 = new Vertex(new Vector3(maxX + deltaMax, minY - 1, minZ - 1));Vertex p3 = new Vertex(new Vector3(minX - 1, maxY + deltaMax, minZ - 1));Vertex p4 = new Vertex(new Vector3(minX - 1, minY - 1, maxZ + deltaMax));this.Tetrahedra.Add(new Tetrahedron(p1, p2, p3, p4));#endregion#region 通过顶点对四面体进行拆分//遍历所有顶点foreach (var vertex in Vertices) {List<Triangle> triangles = new List<Triangle>();//遍历所有现有四面体foreach (var t in this.Tetrahedra) {if (t.CircumCircleContains(vertex.Position)) {//如果包含则标记该四面体需要删除t.IsBad = true;//记录四面体的4个三角形triangles.Add(new Triangle(t.A, t.B, t.C));triangles.Add(new Triangle(t.A, t.B, t.D));triangles.Add(new Triangle(t.A, t.C, t.D));triangles.Add(new Triangle(t.B, t.C, t.D));}}//判断四面体4个三角形是否近似相同,相同则都删除for (int i = 0; i < triangles.Count; i++) {for (int j = i + 1; j < triangles.Count; j++) {if (Triangle.AlmostEqual(triangles[i], triangles[j])) {triangles[i].IsBad = true;triangles[j].IsBad = true;}}}//删除带标记的四面体和三角形this.Tetrahedra.RemoveAll((Tetrahedron t) => t.IsBad);triangles.RemoveAll((Triangle t) => t.IsBad);//将剩余三角形和该顶点重新构成四面体foreach (var triangle in triangles) {this.Tetrahedra.Add(new Tetrahedron(triangle.U, triangle.V, triangle.W, vertex));}}//四面体中删除所有含有初始四面体点的四面体this.Tetrahedra.RemoveAll((Tetrahedron t) => t.ContainsVertex(p1) || t.ContainsVertex(p2) || t.ContainsVertex(p3) || t.ContainsVertex(p4));#endregion#region 提取三角形和边的信息HashSet<Triangle> triangleSet = new HashSet<Triangle>();HashSet<Edge> edgeSet = new HashSet<Edge>();foreach (var t in this.Tetrahedra) {var abc = new Triangle(t.A, t.B, t.C);var abd = new Triangle(t.A, t.B, t.D);var acd = new Triangle(t.A, t.C, t.D);var bcd = new Triangle(t.B, t.C, t.D);if (triangleSet.Add(abc)) {this.Triangles.Add(abc);}if (triangleSet.Add(abd)) {this.Triangles.Add(abd);}if (triangleSet.Add(acd)) {this.Triangles.Add(acd);}if (triangleSet.Add(bcd)) {this.Triangles.Add(bcd);}var ab = new Edge(t.A, t.B);var bc = new Edge(t.B, t.C);var ca = new Edge(t.C, t.A);var da = new Edge(t.D, t.A);var db = new Edge(t.D, t.B);var dc = new Edge(t.D, t.C);if (edgeSet.Add(ab)) {Edges.Add(ab);}if (edgeSet.Add(bc)) {Edges.Add(bc);}if (edgeSet.Add(ca)) {Edges.Add(ca);}if (edgeSet.Add(da)) {Edges.Add(da);}if (edgeSet.Add(db)) {Edges.Add(db);}if (edgeSet.Add(dc)) {Edges.Add(dc);}}#endregion}

源码:

Delaunay2D.cs

Delaunay3D.cs

平面剖分三角形Delaunay算法实现,以及扩展到立体空间中的实现(附源码)相关推荐

  1. Springboot+采用协同过滤算法的家政服务平台的设计与实现 毕业设计-附源码260839

    Springboot家政服务平台 摘  要 协同过滤算法是一种较为著名和常用的推荐算法,它基于对用户历史行为数据的挖掘发现用户的喜好偏向,并预测用户可能喜好的产品进行推荐.基于协同过滤算法的家政服务平 ...

  2. springboot+mysql+采用协同过滤算法的家政服务平台的设计与实现 毕业设计-附源码260839

    Springboot家政服务平台 摘  要 协同过滤算法是一种较为著名和常用的推荐算法,它基于对用户历史行为数据的挖掘发现用户的喜好偏向,并预测用户可能喜好的产品进行推荐.基于协同过滤算法的家政服务平 ...

  3. 智能优化算法之遗传算法(GA)的实现(基于二进制编码,Python附源码)

    文章目录 一.遗传算法的实现思路 二.基于二进制编码方式的遗传算法的实现 1.库的导入 2.目标函数 3.个体编码函数 4.个体解码函数 5.选择函数 6.交叉函数 7.变异函数 8.算法主流程 一. ...

  4. SHA3系列(KECCAK)哈希算法原理及实现(附源码)

    相关文章: (本文持续更新中) SHA3系列(KECCAK)哈希算法原理及实现(附源码) SHA512系列哈希算法原理及实现(附源码) SHA224和SHA256哈希算法原理及实现(附源码) 国密SM ...

  5. SHA512系列哈希算法原理及实现(附源码)

    相关文章: SHA512系列哈希算法原理及实现(附源码) SHA224和SHA256哈希算法原理及实现(附源码) 国密SM3哈希算法原理及实现(附源码) SHA1哈希算法原理及实现(附源码) MD5哈 ...

  6. java毕业设计——基于java+MMAS的蚁群算法路由选择可视化动态模拟设计与实现(毕业论文+程序源码)——蚁群算法路由选择可视化动态模拟

    基于java+MMAS的蚁群算法路由选择可视化动态模拟设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+MMAS的蚁群算法路由选择可视化动态模拟设计与实现,文章末尾附有本毕业设计的 ...

  7. MATLAB应用实战系列(五十三)-模拟退火算法(附源码)

    模拟退火算法 模拟退火算法在处理全局优化.离散变量优化等困难问题中,具有传统优化算法无可比拟的优势.这里描述模拟退火算法的原理及其基本框架结构,给出用模拟退火算法求解TSP问题的具体实现方法 以下是我 ...

  8. 反光衣识别算法冠军方案总结(附源码)|极市打榜

    反光衣识别算法冠军方案总结(附源码)|极市打榜 原创 CV开发者都爱看的 [极市平台](javascript:void(0)

  9. SHA224和SHA256哈希算法原理及实现(附源码)

    相关文章: SHA224和SHA256哈希算法原理及实现(附源码) 国密SM3哈希算法原理及实现(附源码) SHA1哈希算法原理及实现(附源码) MD5哈希算法原理及实现(附源码) MD4哈希算法原理 ...

最新文章

  1. apache安装_Apache+PHP 安装 ---windows
  2. c语言 左补1,转专业后对于C语言补修的一些体会(1)
  3. matlab生成wav文件并用python验证
  4. 信用评分卡模型的理论准备
  5. SAP Cloud for Customer里的ticket回复UI的实现
  6. 麒麟 810 实体芯片亮相;1325 个安卓应用私自搜集数据;Linux Kernel 5.2 发布 | 极客头条...
  7. 关系抽取之分段卷积神经网络(PCNN)
  8. CallStack获取函数堆栈
  9. 批改网作文提交时分析不出来_推荐一款免费英语写作批改软件
  10. vue系列(三)——手把手教你搭建一个vue3管理后台基础模板
  11. 中国第一大忽悠终于倒下了
  12. 电视收视率评估工具推荐
  13. Win11调整分区大小的方法有哪些?
  14. 智能优化算法之蚁群算法(ACO)
  15. Geometry Processing 几何处理 7
  16. 吉大计算机学院课外八学分,西安交通大学本科“课外8学分”实施办法
  17. 在网页中插入一个透明背景的PNG图片
  18. 企业常用的Nginx网站服务相关配置
  19. “大瓜”接二连三,微博靠什么不宕机?
  20. 大年初二 | 华章图书祝您福到旺到财运到

热门文章

  1. 机器人潘森护盾_官方公布最难的四大操作,机器人Q闪排第二,他的R闪是终极难度...
  2. Photoshop中的快速复制
  3. 新的TPM 2.0漏洞可能让黑客窃取加密密钥
  4. 测试技术大牛谈成长经历:一个好的软件测试工程师应该做到这些!
  5. catia中sew的用法_CATIA测量工具的用法
  6. 帝国cms怎样去掉面包屑导航里的隐藏栏目
  7. 分组函数——MySQL
  8. C# 使用NPOI库导出excel表格
  9. Linux常用命令for QA-数据脱敏版1
  10. POJ 2983 浅谈差分约束系统处理严格等价性问题