日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Delaunay triangulation network怎么理解

發(fā)布時(shí)間:2024/1/1 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Delaunay triangulation network怎么理解 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

三角形分割
之前畫球的時(shí)候,因?yàn)橄氚亚虻哪P妥兂?Wavefront .obj file,所以當(dāng)時(shí)想的是分割辦法是這樣來(lái)分割三角形:

包括之前嘗試用Beizer曲線來(lái)畫Utah teapot也都是采用的這樣的辦法,根據(jù)生成的一層一層的點(diǎn)來(lái)分割三角形。

然而其實(shí)針對(duì)這一類情況,比如有一堆頂點(diǎn),我們想把它們分割成三角形,是有專門的算法來(lái)做這些事的 - Triangulation, 也就是三角形分割。其中最出名的算法是 Delaunay triangulation (德勞內(nèi)三角化),這個(gè)算法可以把平面上的點(diǎn)分割成具有良好性質(zhì)的三角形。

所謂良好性質(zhì)是指在 Delaunay triangulation 的時(shí)候,它會(huì)最大化生成的所有三角形的內(nèi)角,會(huì)盡量避免 sliver triangle。所謂 sliver triangle 就是可能會(huì)有一個(gè)或者兩個(gè)很尖銳的角的三角形,這樣的三角形在線性插值的時(shí)候可能效果不太好。所以一般會(huì)想要避免。

Delaunay triangulation
以四個(gè)點(diǎn)為例,可以有以下的兩種三角化方式:

根據(jù)我們希望避免 sliver triangle 的角度來(lái)看第一種比第二種好。

Delaunay triangulation 就會(huì)生成第一種分割。

平面上的點(diǎn)集 P 的 德勞內(nèi)三角化 是一種 三角剖分 DT§,使得在 P 中沒(méi)有點(diǎn)嚴(yán)格處于 DT§ 中任意一個(gè)三角形 外接圓 的內(nèi)部。

D 位于 △ABC 外接圓的外部 √
A 位于 △BCD 外接圓的外部 √

C 位于 △ABD 外接圓的外部 ×
B 位于 △ACD 外接圓的外部 ×
其實(shí)很容易看出來(lái),如果點(diǎn)在三角形的外接圓的內(nèi)部就很容易造成比較尖銳的角。

當(dāng)然也可能四個(gè)點(diǎn)在同一個(gè)圓上,這里以及以下我們暫時(shí)都不討論共圓和三點(diǎn)共線這種稍顯特殊的情況。

Voronoi diagram
Delaunay triangulation 是 Voronoi Diagram(沃羅諾伊圖)的 Dual(對(duì)偶圖).

所謂 Dual(對(duì)偶圖),看以下例子:比如藍(lán)色的是圖G,紅色的圖就是它的對(duì)偶圖。

藍(lán)色的圖有四個(gè)面: f1, f2, f3, f4
四個(gè)面中取四個(gè)頂點(diǎn) v1, v2, v3, v4
對(duì)于那些由一條edge分割的面,比如 f1-f2, f2-f3,f2-f4,直接連起來(lái) v1-v2, v2-v3,v2-v4 形成edge
對(duì)于f3-f4,f1-f4這種不是由一條edge分割的面,需要連接v3-v4,v1-v4 形成回路

沃羅諾伊圖是根據(jù)到平面特定子集中點(diǎn)的距離將平面劃分為區(qū)域的圖,該點(diǎn)集(稱為種子,站點(diǎn)或生成器)是預(yù)先指定的,并且對(duì)于每個(gè)種子,都有一個(gè)對(duì)應(yīng)的區(qū)域,該區(qū)域由比該種子更近的所有點(diǎn)(比其他種子更近)組成。
如果平面上就兩個(gè)點(diǎn),那么 Voronoi 圖就是這兩個(gè)點(diǎn)的中垂線分割:

再增加一個(gè)點(diǎn),中垂線繼續(xù)出來(lái)分割:

比較容易理解 Delaunay triangulation 和 Voronoi diagram 的關(guān)系,畢竟外接圓這個(gè)就隱含了跟誰(shuí)距離更近。

Parabolic Lifting Algorithm
找 Delaunay Triangulation 也可以轉(zhuǎn)化為一個(gè)找 Convex Hull 的問(wèn)題,把2d平面上的每個(gè)點(diǎn)P升到空中并且給它的z坐標(biāo)是 [公式] ,然后找到這些點(diǎn)構(gòu)成的 bottom convex hull,把它們?cè)儆成浠?d平面。

之所以這樣可行覺(jué)得因?yàn)?#xff1a;

圓的方程式可寫成 [公式] (寫成圓心式展開(kāi)可得)
三點(diǎn)確定一個(gè)平面: [公式]
這個(gè)平面與 [公式] 相交
三點(diǎn)確定的平面與拋物面相交的結(jié)果:

[公式]

得到的也就是圓,所以這樣可以保證三點(diǎn)確定一個(gè)圓,也就是一個(gè)三角形有一個(gè)外接圓。

Coding Algorithm
然而在代碼時(shí)候,convex hull不一定是最好的方法,發(fā)現(xiàn)了這篇三角剖分算法(delaunay),里面提到了這個(gè)算法:

subroutine triangulate
input : vertex list
output : triangle list
initialize the triangle list
determine the supertriangle
add supertriangle vertices to the end of the vertex list
add the supertriangle to the triangle list
for each sample point in the vertex list
initialize the edge buffer
for each triangle currently in the triangle list
calculate the triangle circumcircle center and radius
if the point lies in the triangle circumcircle then
add the three triangle edges to the edge buffer
remove the triangle from the triangle list
endif
endfor
delete all doubly specified edges from the edge buffer
this leaves the edges of the enclosing polygon only
add to the triangle list all triangles formed between the point
and the edges of the enclosing polygon
endfor
remove any triangles from the triangle list that use the supertriangle vertices
remove the supertriangle vertices from the vertex list
end
然后有優(yōu)化版本:

input: 頂點(diǎn)列表(vertices) //vertices為外部生成的隨機(jī)或亂序頂點(diǎn)列表
output:已確定的三角形列表(triangles)
    初始化頂點(diǎn)列表
    創(chuàng)建索引列表(indices = new Array(vertices.length)) //indices數(shù)組中的值為0,1,2,3,…,vertices.length-1
    基于vertices中的頂點(diǎn)x坐標(biāo)對(duì)indices進(jìn)行sort  //sort后的indices值順序?yàn)轫旤c(diǎn)坐標(biāo)x從小到大排序(也可對(duì)y坐標(biāo),本例中針對(duì)x坐標(biāo))
    確定超級(jí)三角形
    將超級(jí)三角形保存至未確定三角形列表(temp triangles)
    將超級(jí)三角形push到triangles列表
    遍歷基于indices順序的vertices中每一個(gè)點(diǎn)   //基于indices后,則頂點(diǎn)則是由x從小到大出現(xiàn)
      初始化邊緩存數(shù)組(edge buffer)
      遍歷temp triangles中的每一個(gè)三角形
        計(jì)算該三角形的圓心和半徑
        如果該點(diǎn)在外接圓的右側(cè)
          則該三角形為Delaunay三角形,保存到triangles
          并在temp里去除掉
          跳過(guò)
        如果該點(diǎn)在外接圓外(即也不是外接圓右側(cè))
          則該三角形為不確定 //后面會(huì)在問(wèn)題中討論
          跳過(guò)
        如果該點(diǎn)在外接圓內(nèi)
          則該三角形不為Delaunay三角形
          將三邊保存至edge buffer
          在temp中去除掉該三角形
      對(duì)edge buffer進(jìn)行去重 // 這里的去重是只要重復(fù)出現(xiàn)的edges全都去掉,不僅僅是重復(fù)部分,也包括原本的
      將edge buffer中的邊與當(dāng)前的點(diǎn)進(jìn)行組合成若干三角形并保存至temp triangles中
    將triangles與temp triangles進(jìn)行合并
    除去與超級(jí)三角形有關(guān)的三角形
end
跟著算法寫了一個(gè)Python版本:

把隨機(jī)生成的點(diǎn)放在空間中看一下:

looks good!

代碼

參考:

Delaunay_triangulation
Dual graph
Voronoi diagram
Triangulate Efficient Triangulation Algorithm Suitable for Terrain Modelling
三角剖分算法(delaunay)

總結(jié)

以上是生活随笔為你收集整理的Delaunay triangulation network怎么理解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。