一、三角剖分Delaunay算法简介

点集的三角剖分(Triangulation),对数值分析(比如有限元分析)以及图形学来说,都是极为重要的一项预处理技术。尤其是Delaunay三角剖分,由于其独特性,关于点集的很多种几何图都和Delaunay三角剖分相关,如Voronoi图,EMST树,Gabriel图等。Delaunay三角剖分有最大化最小角,“最接近于规则化的“的三角网和唯一性(任意四点不能共圆)两个特点。

EMST(Euclidean minimum spanning tree)

Delaunay 三角剖分广泛应用于许多不同应用程序中的科学计算。虽然有大量的计算三角剖分的算法,但 Delaunay 三角剖分以其实用的几何属性广受欢迎。

Gabriel Graph

基本属性是 Delaunay 规则。如果是二维三角剖分,通常将其称为空外接圆规则。对于一组二维点而言,这些点的 Delaunay 三角剖分可确保与每个三角形相关的外接圆的内部都不包含其他点。这种三角剖分便是 Delaunay 三角剖分。

Delaunay 三角剖分堪称“外形整齐”,原因在于为满足空外接圆属性,优先选择带有较大内角的三角形,而不是带有较小内角的三角形。非 Delaunay 三角剖分中的三角形在顶点 V2 和 V4 处呈锐角。如果将 {V2, V4} 边替换为连接 V1 和 V3 的边,会实现最小角的最大化并且使得该三角剖分变为 Delaunay 三角剖分。另外,Delaunay 三角剖分将最近邻点的点连接在一起。这两个特征(外形整齐和最近邻点关系)在实践中具有重要的作用,有助于促进在散点数据插值中使用 Delaunay 三角剖分。

虽然 Delaunay 属性定义明确,但存在退化点集时三角剖分的拓扑并不唯一。在二维中,4 个或更多特征点位于同一圆中时会引发退化。例如,正方形的顶点不具有唯一的 Delaunay 三角剖分。

二、三角剖分Delaunay算法的源代码


namespace Legalsoft.Truffer.Algorithm
{public struct Vertex{public int x;public int y;public int z;}public struct Triangle{public int vv0;public int vv1;public int vv2;}public class Delaunay{public const int MaxVertices = 500;public const int MaxTriangles = 1000;public Vertex[] Vertex = new Vertex[MaxVertices];public Triangle[] Triangle = new Triangle[MaxTriangles];private bool InCircle(int xp, int yp, int x1, int y1, int x2, int y2, int x3, int y3, double xc, double yc, double r){double eps;double m1;double m2;double mx1;double mx2;double my1;double my2;double dx;double dy;double rsqr;double drsqr;eps = 0.000000001;if (Math.Abs(y1 - y2) < eps && Math.Abs(y2 - y3) < eps){MessageBox.Show("INCIRCUM - F - Points are coincident !!");return false;}if (Math.Abs(y2 - y1) < eps){m2 = (-(Convert.ToDouble(x3) - Convert.ToDouble(x2)) / (Convert.ToDouble(y3) - Convert.ToDouble(y2)));mx2 = Convert.ToDouble((x2 + x3) / 2.0);my2 = Convert.ToDouble((y2 + y3) / 2.0);xc = Convert.ToDouble((x2 + x1) / 2.0);yc = Convert.ToDouble(m2 * (xc - mx2) + my2);}else if (Math.Abs(y3 - y2) < eps){m1 = (-(Convert.ToDouble(x2) - Convert.ToDouble(x1)) / (Convert.ToDouble(y2) - Convert.ToDouble(y1)));mx1 = Convert.ToDouble((x1 + x2) / 2.0);my1 = Convert.ToDouble((y1 + y2) / 2.0);xc = Convert.ToDouble((x3 + x2) / 2.0);yc = Convert.ToDouble(m1 * (xc - mx1) + my1);}else{m1 = (-(Convert.ToDouble(x2) - Convert.ToDouble(x1)) / (Convert.ToDouble(y2) - Convert.ToDouble(y1)));m2 = (-(Convert.ToDouble(x3) - Convert.ToDouble(x2)) / (Convert.ToDouble(y3) - Convert.ToDouble(y2)));mx1 = Convert.ToDouble((x1 + x2) / 2.0);mx2 = Convert.ToDouble((x2 + x3) / 2.0);my1 = Convert.ToDouble((y1 + y2) / 2.0);my2 = Convert.ToDouble((y2 + y3) / 2.0);xc = Convert.ToDouble((m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2));yc = Convert.ToDouble(m1 * (xc - mx1) + my1);}dx = (Convert.ToDouble(x2) - Convert.ToDouble(xc));dy = (Convert.ToDouble(y2) - Convert.ToDouble(yc));rsqr = Convert.ToDouble(dx * dx + dy * dy);r = Convert.ToDouble(Math.Sqrt(rsqr));dx = Convert.ToDouble(xp - xc);dy = Convert.ToDouble(yp - yc);drsqr = Convert.ToDouble(dx * dx + dy * dy);if (drsqr <= rsqr){return true;}return false;}private int WhichSide(int xp, int yp, int x1, int y1, int x2, int y2){double equation;equation = ((Convert.ToDouble(yp) - Convert.ToDouble(y1)) * (Convert.ToDouble(x2) - Convert.ToDouble(x1))) - ((Convert.ToDouble(y2) - Convert.ToDouble(y1)) * (Convert.ToDouble(xp) - Convert.ToDouble(x1)));if (equation > 0){return -1;}else if (equation == 0){return 0;}else{return 1;}}public int Triangulate(int nvert){bool[] Complete = new bool[MaxTriangles];long[,] Edges = new long[3, MaxTriangles * 3 + 1];int Nedge;int xmin;int xmax;int ymin;int ymax;int xmid;int ymid;double dx;double dy;double dmax;int i;int j;int k;int ntri;double xc = 0.0;double yc = 0.0;double r = 0.0;bool inc;xmin = Vertex[1].x;ymin = Vertex[1].y;xmax = xmin;ymax = ymin;for (i = 2; i <= nvert; i++){if (Vertex[i].x < xmin){xmin = Vertex[i].x;}if (Vertex[i].x > xmax){xmax = Vertex[i].x;}if (Vertex[i].y < ymin){ymin = Vertex[i].y;}if (Vertex[i].y > ymax){ymax = Vertex[i].y;}}dx = Convert.ToDouble(xmax) - Convert.ToDouble(xmin);dy = Convert.ToDouble(ymax) - Convert.ToDouble(ymin);if (dx > dy){dmax = dx;}else{dmax = dy;}xmid = (xmax + xmin) / 2;ymid = (ymax + ymin) / 2;Vertex[nvert + 1].x = Convert.ToInt64(xmid - 2 * dmax);Vertex[nvert + 1].y = Convert.ToInt64(ymid - dmax);Vertex[nvert + 2].x = xmid;Vertex[nvert + 2].y = Convert.ToInt64(ymid + 2 * dmax);Vertex[nvert + 3].x = Convert.ToInt64(xmid + 2 * dmax);Vertex[nvert + 3].y = Convert.ToInt64(ymid - dmax);Triangle[1].vv0 = nvert + 1;Triangle[1].vv1 = nvert + 2;Triangle[1].vv2 = nvert + 3;Complete[1] = false;ntri = 1;for (i = 1; i <= nvert; i++){Nedge = 0;j = 0;do{j = j + 1;if (Complete[j] != true){inc = InCircle(Vertex[i].x, Vertex[i].y, Vertex[Triangle[j].vv0].x, Vertex[Triangle[j].vv0].y, Vertex[Triangle[j].vv1].x, Vertex[Triangle[j].vv1].y, Vertex[Triangle[j].vv2].x, Vertex[Triangle[j].vv2].y, xc, yc, r);if (inc){Edges[1, Nedge + 1] = Triangle[j].vv0;Edges[2, Nedge + 1] = Triangle[j].vv1;Edges[1, Nedge + 2] = Triangle[j].vv1;Edges[2, Nedge + 2] = Triangle[j].vv2;Edges[1, Nedge + 3] = Triangle[j].vv2;Edges[2, Nedge + 3] = Triangle[j].vv0;Nedge = Nedge + 3;Triangle[j].vv0 = Triangle[ntri].vv0;Triangle[j].vv1 = Triangle[ntri].vv1;Triangle[j].vv2 = Triangle[ntri].vv2;Complete[j] = Complete[ntri];j = j - 1;ntri = ntri - 1;}}}while (j < ntri);for (j = 1; j <= Nedge - 1; j++){if (Edges[1, j] != 0 && Edges[2, j] != 0){for (k = j + 1; k <= Nedge; k++){if (Edges[1, k] != 0 && Edges[2, k] != 0){if (Edges[1, j] == Edges[2, k]){if (Edges[2, j] == Edges[1, k]){Edges[1, j] = 0;Edges[2, j] = 0;Edges[1, k] = 0;Edges[2, k] = 0;}}}}}}for (j = 1; j <= Nedge; j++){if (Edges[1, j] != 0 && Edges[2, j] != 0){ntri = ntri + 1;Triangle[ntri].vv0 = Edges[1, j];Triangle[ntri].vv1 = Edges[2, j];Triangle[ntri].vv2 = i;Complete[ntri] = false;}}}i = 0;do{i = i + 1;if (Triangle[i].vv0 > nvert || Triangle[i].vv1 > nvert || Triangle[i].vv2 > nvert){Triangle[i].vv0 = Triangle[ntri].vv0;Triangle[i].vv1 = Triangle[ntri].vv1;Triangle[i].vv2 = Triangle[ntri].vv2;i = i - 1;ntri = ntri - 1;}}while (i < ntri);return ntri;}}
}

——————————————————————

POWER BY 315SOFT.COM &
TRUFFER.CN

C#,计算几何,随机点集之三角剖分的德劳内(Delaunay)算法的源代码相关推荐

  1. Delaunay(德劳内)三角剖分算法

    在数学和计算几何领域, 平面上的点集P的德劳内三角化是一种三角剖分 DT(P),使得在 P 中没有点严格处于 DT(P) 中任意一个三角形外接圆的内部.Delaunay 三角化最大化了此三角剖分中三角 ...

  2. 能否构成三角形的条件代码_平面三角形分割 - 德劳内三角化

    三角形分割 之前画球的时候,因为想把球的模型变成 Wavefront .obj file,所以当时想的是分割办法是这样来分割三角形: 包括之前尝试用Beizer曲线来画Utah teapot也都是采用 ...

  3. CAD Delaunay3D插件 三维德劳内三角网

    功能说明 CAD Delaunay3D插件可在AutoCAD内生成三维德劳内三角网,形成Delaunay框架. 插件提供了对齐.交错两种控制点布点方式: 同时可生成线状及实体Delaunay网两种绘图 ...

  4. python下三角代码分析_空间分析:2-3。用Python生成Delaunay三角形,23Python,德劳内

    这篇看怎么用程序生成德洛内三角形. Python3,引用了shapely包,其中triangulate是生成德洛内三角形的方法. from shapely.ops import triangulate ...

  5. 【计算几何】德劳内三角剖分算法 | 利用 scatter 绘制散点图 | 实现外接圆生成 | scipy库的 Dealunay 函数 | 实战: A-B间欧氏距离计算

    猛戳!跟哥们一起玩蛇啊 

  6. 二维Delaunay(德洛内)三角网剖分的matlab实现

    二维Delaunay(德洛内)三角网的matlab实现 二维Delaunay(德洛内)三角网的matlab实现 1.Delaunay三角网的概述 2.Delaunay三角网的算法 3.Delaunay ...

  7. 生长算法实现点集的三角剖分(Python(Tkinter模块))

    生长算法实现点集的三角剖分( Python(Tkinter模块)) 关于三角剖分 假设V是二维实数域上的有限点集,边e是由点集中的点作为端点构成的封闭线段, E为e的集合.那么该点集V的一个三角剖分T ...

  8. 三角剖分与Delaunay三角剖分及带约束的Delaunay三角剖分

    本博客参考 http://blog.csdn.net/raby_gyl/article/details/17409717 http://baike.baidu.com/view/1691145.htm ...

  9. C++smallest circle 获取外接给定点集的最小圆的中心和半径算法(附完整源码)

    C++smallest circle 获取外接给定点集的最小圆的中心和半径算法 C++smallest circle 获取外接给定点集的最小圆的中心和半径算法完整源码(定义,实现,main函数测试) ...

最新文章

  1. Tomcat官方文档关于数据源配置的内容
  2. 解决SecureCRT 链接服务器 中文显示出现乱码【有图有真相】
  3. 企业如何确保精益生产管理真正落地?
  4. linux svn安装
  5. Manage Jenkins管理界面提示“依赖错误: 部分插件由于缺少依赖无法加载...“问题解决办法
  6. maven web项目中的web.xml的版本如何更改
  7. 第7步 mybatis-generator dao层生成器
  8. java Web监听器导图详解
  9. html中如何设置图片填充颜色渐变,实现SVG图标的渐变填充效果
  10. 2013阿里技术嘉年华:阿里数据同步前世今生
  11. 【知识图谱】一文全览,ICLR 2020 上的知识图谱研究
  12. 【渝粤教育】电大中专幼儿园课程论作业 题库
  13. ES6 Generator 函数
  14. optisystem自建matlab信号源仿真
  15. Python数据结构
  16. linux系统chmod 755权限
  17. JavaScript相关文章推荐
  18. 云游戏的架构设计和技术实现
  19. android跳转谷歌地图导航,Android使用intent调取导航或者地图
  20. keil更改黑色背景颜色

热门文章

  1. 了解Sidecar模式
  2. 当这个小女孩分别穿着漂亮和破旧的衣服站在大街上,她经历了两种极端...
  3. 乒乓测评:电视盒子哪个牌子最好?2023电视盒子品牌排行榜
  4. conda安装sklearn
  5. RecyclerView 项目集合
  6. FluentCRM 2.6.0:更多功能、集成改进等等!
  7. 546、Zookeeper详细入门教程系列 -【Zookeeper内部原理】 2022.11.06
  8. android原生主题emui5,Material Theme for Huawei EMUI
  9. Win10安装Cygwin,并安装GCC等软件包
  10. 数学建模——Matlab中rem与mod区别