Delaunay三角形网格

7 篇文章 0 订阅
3 篇文章 0 订阅

cited:http://blog.csdn.net/wypblog/article/details/7249309

【摘要】本文探讨了以平面散点集逐点插入的Delaunay三角化方法为基础,在三角化过程中采用一定策略,将其改进成为一种简单高效的方法。该方法能够适应各种边界,包括多岛、多连通域等复杂情况,能够生成贴体的三角网,网格能够保证符合Delaunay法则。

【关键词】Delaunay  三角网  三角剖分  等值线

 

  三角剖分是计算几何领域的主要课题之一,并具有广泛的应用前景。在计算机图形学、科学计算可视化、自然科学、特别是在地学领域,经常需要处理大量分布于某一区域内的离散数据。由于这些数据分布的不均匀性,就产生了一个如何合理有效地使用这些宝贵数据的问题。Voronoi图和Delaunay三角网是被普遍接受和广泛采用的用于分析研究区域离散数据的有力工具。当然,它不仅适用于地学,而且活跃于所有与简单三维分析有关的领域。

但经典的方法只能在平面散点集的凸集上构建,并且效率性态差,即随着点数的增加耗时急剧增加。为了适应工程的需要,本文改进了逐点插入法,使之成为简单易行具快捷高效的方法,并能适应各种边界,包括多岛、多连通域、凹边界等复杂情况。

1 Voronoi多边形和Delaunay三角网的定义及其性质[1]

设x为平面上的点,则区域V(i)={x∈E2|d(x,vi)≤d(x,vj), j=1,2,...,N, j≠I}称为Voronoi多边形(简称V-多边形)。各点的V-多边形共同组成Voronoi-图(简称V-图)。

Delaunay三角网的定义:有公共边的V-多边形称为相邻的V-多边形。连接所有相邻的V-多边形的生长中心所形成的三角网称为Delaunay三角网(简称D-三角网)。

D-三角网的外边界是一个凸多边形,它由节点集中的凸集形成,通常称为凸壳。D-三角网具有两个非常重要的性质。

(1)空外接圆性质:在由点集V所形成的D-三角网中,其每个三角形的外接圆均不包含点集V中的其他任意点。

(2)最大的最小角度性质:在由点集V所能形成的三角网中,D-三角网中三角形的最小角度是最大的。

由于这两个性质,决定了D-三角网具有极大的应用价值。同时,它也是二维平面三角网中唯一的、最好的。

2 改进方法中的数据结构

首先将需要三角剖分的点分为散点和边界点,边界点按一定的顺序(逆时针或顺时针)排列。点的数据结构为单向链表,定义如下。

typedef struct Vertex{

       int ID; //ID号

       double x,y,z;//坐标值

       char mark;//材料、边界标记,区分散点、外边界点、内边界点

       struct Vertex *next;//下一个节点

}* PVERTEX,VERTEX;

      三角形单元的定义是三角剖分的基础,必须定义很好的结构表达三角形的拓扑结构,以提高算法的效率,并且必须方便三角形单元在三角网中脱离拓扑结构。本文定义如下。

         typedef struct Triangle{

       struct Edge *pe[3];//指向三角形的三个边

       struct Vertex *pv[3];//指向三角形的三个顶点

       int ID; //ID号

       struct Triangle *next,*pre;//指向前后的三角形

}* PTRIANGLE,TRIANGLE;

        三角形单元的拓扑结构还要通过边来实现,边的定义为:

typedef struct Edge{

       struct Vertex *pv[2];//指向该边的两个顶点

       struct Triangle *pt[2];//指向该边所属于的两个三角形

       struct Edge *next,*pre;//指向前后的边

} *PEDGE, EDGE;

边界链表的定义如下:

typedef struct BndChain{

       struct Vertex *chain;//一个边界

       char mark;//边界标记,区分散点、外边界点、内边界点内边界点

       struct BndChain *next;//下一个边界

}*PBNDCHAIN,BNDCHAIN;

3 判断一个点是否落在一个任意形状的多边形内的方法

一般来说,判断一个点是否落在一个任意形状的多边形内比较困难。本文使用了一种较为简单的方法来判断。

                          

                                   图1

输入为按一定顺序(逆时针或顺时针)排列的边界点集p1,p2,…pn,及点p的坐标。判断依据为:如果点落在多边形之外,则点与有向线段 所对应的有向弧的角度之和等于0;如果落在多边形之内,则有向弧的角度之和的绝对值等于2π,如图1。                                                                 

4 核心算法

    Tsai根据实现过程,把生成D-三角网的各种算法分为三类:分治算法、逐点插入法、三角网生长法[2]。本文采用逐点插入法,其核心思想[3]是:当添加一个新点时,找出包含此点的三角形(包括在三角形的边上)。如果落在三角形内,将此点与三角形的三个定点连接,并将三角形的三条边送入优化队列,按照Delaunay三角网的两个性质进行优化;如果落在三角形的边上,删除此边,重新建立两条新边,并将其余两边或四边(有公边的相邻三角形)送入优化队列优化。

5 优化算法

(1)从优化队列中取出一条边,开始优化此边。

(2)如果此边属于边界边,则此边不用优化。

(3)如果此边所在的正在被优化的三角形的外接圆包含了公用此边的三角形的除此边外的另一个顶点,将当前的优化边从优化队列中删除,将当前被优化的三角形删除,同时将该三角形的另外的两边加入到优化队列中;否则,将此边从优化队列中删除后送入优化后的队列,便于建立新的三角形单元。

(4)重复(1),(2),(3)步,直到优化队列为空。 

 

最近点意义下的Voronoi图的直线对偶图就是Delaunay三角剖分,因此可以把上上篇描述的构造Voronoi图的分治算法用于Delaunay三角剖分。

增量算法:易于实现,使用广泛,适合小规模点集的三角化。具体过程如下:

1 遍历所有散点,生成一个包含所有散点的大三角形(顶点不在点集中)

2 有未处理过的点p,插入之,否则结束算法,退出

3 在已剖分好的三角网中找出包含点p的三角形t,把p与t的三个顶点相连,构成三个三角形

4 根据优化准则对局部生成的三角形进行优化(互换对角线等)

5 返回第2步

局部变换法:根据Delaunay三角剖分的性质2,首先构造一个不满足Delaunay三角剖分条件的三角网络,然后对两个共边三角形构成的凸四边形迭代换边使之满足Delaunay三角剖分的条件(主要是交换对角线的方法)

 

 

Delaunay三角剖分具有下列性质:

(1)Delaunay三角剖分所形成的三角形中,最小的内角是所有三角剖分中最大的。故Delaunay三角剖分所形成的三角形最接近于等边三角形,在很多应用中具有最优的性质。此性质等价于Delaunay三角剖分所形成的三角形的外接圆内不包含其他点。

(2)如果任意四点不共圆,则该四点只能形成唯一的Delaunay三角,否则不唯一。故可推知,对Delaunay三角剖分的局部确保可以保证使整体确保满足Delaunay三角剖分。

(3)在已Delaunay三角化的网格中加入一点P,只需要删除所有外接圆包含此点的三角形,并连接P与所有可见的点(即连接后不会与其他边相交),则形成的网格仍然满足Delaunay三角剖分的条件。

 

1、增量算法

该算法基于性质(3),算法简单,时间复杂度为O(nlogn),

使用广泛,基本步骤如下:

(1)生成一个包含所有点的大三角形(其定点不在点集中);

(2)对点集中的每个点,根据性质(3)进行处理(不删除大三角形的边);

(3)删除所有与大三角形相关的边。

该算法的时间主要用于对外接圆的搜索和对顶点的连接。其中,前者可以使用指南针算法进行优化;后者可以对点集进行排序,使加入网格的点均匀分布来降低复杂度。

2、局部变换法

该算法基于性质(2),首先构造一个不满足Delaunay三角剖分条件的三角网格,再对两个共边三角形构成的凸四边形迭代换边使之满足Delaunay三角剖分的条件(主要是交换对角线的方法)。

利用delaunay函数划分网格欢迎指点探讨-DelaunayWithGrid.m 本帖最后由 liuf412044725 于 2013-6-8 17:47 编辑 近期论坛上有不少讨论delaunay函数的帖子。似乎主要有以下问题: 1、delaunay函数各参数的意义 2、知道几何边界时,用delaunay函数划分三角形网格由于区域内部没有点,质量很差,怎么改进 3、怎样避免产生过于狭长的delaunay 三角形 4、 凹多边形的情况怎么处理 第1个问题,看看帮助应该能解决。第2个问题,delaunay本来是用来对离散点进行三角剖分,内部没有点时并不合适。除非特别处理。第3个问题,估计是利用delaunay和meshgrid来划网格,边界附近会产生狭长的delaunay 三角形,这个也可以做特别处理。第4个问题,可以用在划分好网格后删掉域外的三角形即可。 由于我也经常使用delaunay来处理背景积分问题,因此仔细琢磨了一下用delaunay来划分已知边界的几何区域的可行方案,在此和大家分享一下,也是抛砖引玉,希望大家有更好的方法。 方案一:先对区域delaunay剖分,删掉域外的三角形,然后将剩下的三角形的边细分,得到新的离散点,然后再次delaunay剖分,然后再次细分边,这样循环下去,直到达到一定的尺寸为止 方案二:利用delaunay和meshgrid函数。将边界细分得到相比原区域边界更加密集边界点,用meshgrid得到包含整个区域的点,将域内的点和边界点一起delaunay 剖分。 讨论: 方案一对于一开始就有很小边界段的情况情况较差,容易出现狭长单元(比如边界有圆弧的话属于这种情况)。还有就是前一步的边界轮廓很清楚,看着别扭。方案二中间的网格能搞保证形状较好。对于边界附近的内部点,容易导致边界单元畸变,可以将离边界太近的点进行删除,这样得到的形状比较好 综合来说,方案二较好,尤其是当删掉离边界太近的内部点。贴出程序,望大家多多指点,共同进步。 P.S. 当然,matlab自身也有很好的网格划分函数,在pdetool中有用到,不过关于几何描述那块比较难以理解(我不是很理解)。另外matlab语言写的划分网格的程序很多,网上可以找到不少很优秀的。这里仅限于简单的使用delaunay来划分。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值