Delaunay三角网在空间邻近分析上是一种较好的支持模型, 广泛应用于空间聚类、多边形群的合并、人像关键点提取、形态分析中。

问题:一堆二维点中寻找一个与目标点最近(欧氏距离最小)的点。

1. 三角剖分与Delaunay剖分的定义

   如何把一个散点集合剖分成不均匀的三角形网格,这就是散点集的三角剖分问题,散点集的三角剖分,对数值分析以及图形学来说,都是极为重要的一项预处理技术。该问题图示如下:
  

1.1. 三角剖分定义

  【定义】三角剖分:假设V是二维实数域上的有限点集,边e是由点集中的点作为端点构成的封闭线段, E为e的集合。那么该点集V的一个三角剖分T=(V,E)是一个平面图G,该平面图满足条件:

  1. 除了端点,平面图中的边不包含点集中的任何点。
  2. 没有相交边。
  3. 平面图中所有的面都是三角面,且所有三角面的合集是散点集V的凸包。

1.2. Delaunay三角剖分的定义

  在实际中运用的最多的三角剖分是Delaunay三角剖分,它是一种特殊的三角剖分。先从Delaunay边说起:
  【定义】Delaunay边:假设E中的一条边e(两个端点为a,b),e若满足下列条件,则称之为Delaunay边:存在一个圆经过a,b两点,圆内(注意是圆内,圆上最多三点共圆)不含点集V中任何其他的点,这一特性又称空圆特性。
  【定义】Delaunay三角剖分:如果点集V的一个三角剖分T只包含Delaunay边,那么该三角剖分称为Delaunay三角剖分。

1.3.Delaunay三角剖分的准则

  要满足Delaunay三角剖分的定义,必须符合两个重要的准则:

  1. 空圆特性:Delaunay三角网是唯一的(任意四点不能共圆),在Delaunay三角形网中任一三角形的外接圆范围内不会有其它点存在。如下图所示:
      

  2. 最大化最小角特性:在散点集可能形成的三角剖分中,Delaunay三角剖分所形成的三角形的最小角最大。从这个意义上讲,Delaunay三角网是“最接近于规则化的“的三角网。具体的说是指在两个相邻的三角形构成凸四边形的对角线,在相互交换后,六个内角的最小角不再增大。如下图所示:

  

1.4.Delaunay三角剖分的特性

   以下是Delaunay剖分所具备的优异特性:

  1. 最接近:以最近临的三点形成三角形,且各线段(三角形的边)皆不相交。
  2. 唯一性:不论从区域何处开始构建,最终都将得到一致的结果。
  3. 最优性:任意两个相邻三角形形成的凸四边形的对角线如果可以互换的话,那么两个三角形六个内角中最小的角度不会变大。
  4. 最规则:如果将三角网中的每个三角形的最小角进行升序排列,则Delaunay三角网的排列得到的数值最大。
  5. 区域性:新增、删除、移动某一个顶点时只会影响临近的三角形。
  6. 具有凸多边形的外壳:三角网最外层的边界形成一个凸多边形的外壳。

1.5.局部最优化处理

  理论上为了构造Delaunay三角网,Lawson提出的局部优化过程LOP(Local Optimization Procedure),一般三角网经过LOP处理,即可确保成为Delaunay三角网,其基本做法如下所示:

  1. 将两个具有共同边的三角形合成一个多边形。
  2. 以最大空圆准则作检查,看其第四个顶点是否在三角形的外接圆之内。
  3. 如果在,修正对角线即将对角线对调,即完成局部优化过程的处理。
      LOP处理过程如下图所示:

  

2.Delaunay剖分的算法

  Delaunay剖分是一种三角剖分的标准,实现它有多种算法。

2.1.Lawson算法

  逐点插入的Lawson算法是Lawson在1977年提出的,该算法思路简单,易于编程实现。基本原理为:首先建立一个大的三角形或多边形,把所有数据点包围起来,向其中插入一点,该点与包含它的三角形三个顶点相连,形成三个新的三角形,然后逐个对它们进行空外接圆检测,同时用Lawson设计的局部优化过程LOP进行优化,即通过交换对角线的方法来保证所形成的三角网为Delaunay三角网。
  上述基于散点的构网算法理论严密、唯一性好,网格满足空圆特性,较为理想。由其逐点插入的构网过程可知,遇到非Delaunay边时,通过删除调整,可以构造形成新的Delaunay边。在完成构网后,增加新点时,无需对所有的点进行重新构网,只需对新点的影响三角形范围进行局部联网,且局部联网的方法简单易行。同样,点的删除、移动也可快速动态地进行。但在实际应用当中,这种构网算法当点集较大时构网速度也较慢,如果点集范围是非凸区域或者存在内环,则会产生非法三角形。

2.2.Bowyer-Watson算法

  Lawson算法的基本步骤是:
  1. 构造一个超级三角形,包含所有散点,放入三角形链表。
  2. 将点集中的散点依次插入,在三角形链表中找出其外接圆包含插入点的三角形(称为该点的影响三角形),删除影响三角形的公共边,将插入点同影响三角形的全部顶点连接起来,从而完成一个点在Delaunay三角形链表中的插入。
  3. 根据优化准则对局部新形成的三角形进行优化。将形成的三角形放入Delaunay三角形链表。
  4. 循环执行上述第2步,直到所有散点插入完毕。
  这一算法的关键的第2步图示如下:

Ref:
[图形算法]Delaunay三角剖分算法
https://zhuanlan.zhihu.com/p/42331420

scipy API - scipy.spatial.Delaunay


python示例:

用 Python 实现 Delaunay Triangulation。
how-to-set-a-maximum-distance-of-a-delaunay-triangle-side 最大边长

#
# http://fangs.in/post/python/pythondelaunay/
#
from scipy.spatial import Delaunay
import numpy as np
import matplotlib.pyplot as plt# Triangle Settings
width = 100
height = 60
pointNumber = 500
np.random.seed(2020)
points = np.zeros((pointNumber, 2))
points[:, 0] = np.random.randint(0, width, pointNumber)
points[:, 1] = np.random.randint(0, height, pointNumber)# Use scipy.spatial.Delaunay for Triangulation
tri = Delaunay(points)# Plot Delaunay triangle with color filled
# 每个三角的中心点
center = np.sum(points[tri.simplices], axis=1)/3.0
# 1.设置color,使距离整个点集中心越近的,颜色越深
# color = np.array([(x - width/2)**2 + (y - height/2)**2 for x, y in center])
# 2.设置color,使点越密集的地方,颜色越深。
color_list = []
thresh_color = 12
for index, sim in enumerate(points[tri.simplices]):cx, cy = center[index][0], center[index][1]x1, y1 = sim[0][0], sim[0][1]x2, y2 = sim[1][0], sim[1][1]x3, y3 = sim[2][0], sim[2][1]# s是simplices的三个顶点到中心的距离的和s = ((x1-cx)**2+(y1-cy)**2)**0.5 + ((cx-x3)**2+(cy-y3)**2)**0.5 + ((cx-x2)**2+(cy-y2)**2)**0.5if s < thresh_color:color_list.append(s)else:color_list.append(thresh_color+1)
color = np.array(color_list)
print('color-mean', np.mean(color))# 三角形边长
side_list = []
thresh_len = 7.5
long_edges = set()
for tr in tri.simplices:for i in range(3):edge0 = tr[i]edge1 = tr[(i+1)%3]p0 = points[ edge0 ]p1 = points[ edge1 ]side = np.linalg.norm(p1 - p0) # 二范数求距离side_list.append(side)if side > thresh_len:long_edges.add((edge0, edge1))
len_sides = np.array(side_list)
print(np.min(len_sides), np.max(len_sides), np.mean(len_sides))# 画出三角
plt.figure(figsize=(10, 6))
plt.tripcolor(points[:, 0], points[:, 1], tri.simplices.copy(), facecolors=color, edgecolors='k')
# plt.scatter(points[:,0],points[:,1], color='r')
# 画出边长较大的三角的顶点
for a,b in long_edges:plt.scatter(points[[a,b], 0], points[[a,b], 1], color='b')# ======================================
ax = plt.gca()
ax.spines['right'].set_color('none')
# ax.spines['bottom'].set_color('none')
# ax.spines['left'].set_color('none')
ax.spines['top'].set_color('none')# Save picture
# plt.savefig('Delaunay1.png', transparent=True, dpi=600)
plt.show()

输出图片:

Delaunay三角剖分算法初探相关推荐

  1. 在几何图形中均匀随机取点算法总结及Delaunay三角剖分算法介绍

    在工作中遇到一个需求,需要在圆形 矩形,三角形内随机,尽量均匀取点作为位置信息,但是random得到的信息有时候不是很满意. 这里讨论一下 第一种错误思路: 根据圆的解析式 (假设圆心在原点)我们可以 ...

  2. MATLAB小技巧(2)Delaunay三角剖分算法

    MATLAB小技巧(2)Delaunay三角剖分算法 前言 一. MATLAB仿真一 二. MATLAB仿真二 三. MATLAB仿真三 四. 小结 前言 MATLAB进行图像处理相关的学习是非常友好 ...

  3. Delaunay三角剖分算法介绍

    一.什么是Delaunay三角剖分 从事数值计算相关领域的读者,相信或多或少都听说过"三角剖分"这个概念.在诸如有限元仿真,光线追踪渲染等计算当中,都需要把几何模型转化为三角网格数 ...

  4. delaunay三角剖分算法——分治算法概述与实现1

    参考网址: https://www.cnblogs.com/zhiyishou/p/4430017.html https://www.cnblogs.com/soroman/archive/2007/ ...

  5. 基于C++(MFC)的二维Delaunay三角剖分与Voronoi图的算法及代码

    一. Delaunay三角网 Delaunay三角网的特性: (1)空圆性,任一三角形外接圆内部不包含其他点. (2)最接近:以最近临的三点形成三角形,且各线段(三角形的边)皆不相交. (3)唯一性: ...

  6. Delaunay 三角剖分2D(原理 + 源码)

    文章目录 Delaunay 三角剖分 代码实现< C++版本 > 代码实现< Python 版本 > 代码实现< Matlab 版本 > 彩蛋:一个很牛掰的算法学习 ...

  7. 【opencv450-samples】delaunay 三角剖分和 voronoi 细分

    该程序演示了 delaunay 三角剖分和 voronoi 细分的迭代构造. This program demonstrates iterativeconstruction of delaunaytr ...

  8. python怎么画人脸代码,OpenCV-Python 绘制人脸 Delaunay 三角剖分(人脸识别核心技术之一)...

    1,介绍 开始之前,向大家提前说声抱歉,上一篇文章末尾提到了,在这篇文章将给大家介绍关于用 OpenCV 实现人脸融合技术,由于人脸融合技术所需的知识储备有点多,不只是之前介绍的的特征点提取,还有本文 ...

  9. 【计算几何】Delaunay 三角剖分原理与实现

    摘 要: 平面点集的三角剖分在数值分析以及图形领域,都是极为重要的一项预处理技术.作为一种广泛应用的三角剖分技术,Delaunay三角剖分通过最大化最小角确保接近与规则的三角网和唯一性.本文通过概述 ...

最新文章

  1. 云曦服务器,云曦南羡最新章节_云曦南羡全本小说
  2. IntelliJ IDEA 常用设置 1
  3. 诺基亚S40手机联系人导入安卓手机
  4. Apache Spark 2.2.0 中文文档 - 概述 | ApacheCN
  5. sliverappbar高度,SliverAppBar的最小高度(颤振)?
  6. 昨天,JetBrains 推出“下一代 IDE”,对标VS Code?快看看有哪些值得期待的功能!...
  7. C++ 继承语法及修饰符
  8. Aspose.Cells 使用UnMerge()取消合并单元格(取消合并单行,取消合并单列,取消多行多列)
  9. ajax 传递请求参数
  10. 别轻易说,我热爱编程,热爱学习
  11. python12306抢票_Python 版 12306 抢票神器
  12. 虚拟偶像PK现实偶像,哪个更能发挥粉丝经济效应?
  13. 淘宝美工设计需要掌握什么技能 ?小白如何快速学会美工设计?
  14. dsa数字签名算法_密码学中的数字签名算法(DSA)
  15. MySql高级(教学版)
  16. C++大数乘加减除比较操作集(含测试原码)
  17. oracle add_months()函数
  18. 转:代码之美——Doom3源代码赏析
  19. 又土又木到不土不木——《土力学原理十记》全笔记(修正版)
  20. 基于ANFIS的有色噪声抵消技术

热门文章

  1. StarGAN生成器结构
  2. 关于 InnoDB 存储引擎的一些总结!
  3. 轻巧易用的平替耳机,质量确实过关,QCY T17真无线耳机上手
  4. Android开源项目:贴纸标签相机,快给你的图片贴上贴纸打上标签吧!~
  5. Java学生成绩查询系统系统
  6. Unable to connect to localhost:6379
  7. 计算等额本金和等额本息的还款详情的软件
  8. matlab fis编辑器在哪,基本FIS编辑器
  9. openlayers6 使用svg格式图片作为Icon标记
  10. 送给女朋友的心形照片墙