構造voronoi圖分治算法

 

 使用前篇介紹的數據結構

輸入:座標平面內的n>1個無重合的點組成的點集P

輸出:構造好的VoronoiV(P)

 

1                對這n個點按照x座標值爲主關鍵字,y座標值爲次關鍵字進行排序

2                開始構造:

2.1        if  n==2  then 構造兩個點的Voronoi圖,並返回

2.2        if  n==3  then 構造三個點的Voronoi圖,並返回

2.3        n個點平均分成兩部分Pl,Pr

2.4        把點集Pl構造成Voronoi V(Pl)

2.5        把點集Pr構造成Voronoi V(Pr)

2.6        合併V(Pl)V(Pr)V(P)

2.7        返回V(P)

 

輸入:已生成的V(Pl),V(Pr)

輸出:合併後的V(P),P=PlUPr

 

1        分別求Pl,Pr的凸包CH(Pl)CH(Pr)

2        BCT ß bottomConnected_tangent(CH(Pl)CH(Pr))

3        UCT ß upConnected_tangent(CH(Pl)CH(Pr))

4        L ß left point of BCT 

Rß right point of BCT

5        while (not (BCT =UCT)) do

5.1        isRight ß isLeft ß false

5.2        initEdge(edgeLedgeRLR)

5.3        insertEdge(LedgeL)

insertEdge(RedgeR)

5.4        /*Pr中與R相鄰的點進行測試(以順時針的方向)

5.4.1        pre ß RedgeR順時針方向下一個半邊節點

5.4.2        if pre != NULL and pre關聯的點在LR向量的左側 then

5.4.2.1  pre1 ß Rpre順時針方向下一個半邊節點

5.4.2.2  while pre1 != NULL and pre1關聯的點在LRpre組成的三角形外接圓內  do

5.4.2.2.1        deleteEdge(pre)

5.4.2.2.2        pre ß pre1

5.4.2.2.3        pre1 ß Rpre順時針方向下一個半邊節點

5.4.3        else isRight ß true

     

5.5        /*Pl中與L相鄰的點進行測試(以逆時針方向)

5.5.1        next ß LedgeL逆時針方向下一個半邊節點

5.5.2        if next!=NULL and next關聯的點在RL向量的右側

5.5.2.1  next1 ß Lnext逆時針方向下一個半邊節點

5.5.2.2  while next1 !=NULL and next1關聯的點在LRnext組成的三角形外接圓內 do

5.5.2.2.1        deleteEdge(next)

5.5.2.2.2        next ß next1

5.5.2.2.3        next1ß Lnext逆時針方向下一個半邊節點

5.5.3        else isLeft ß true

5.6        if isRight then L ß next關聯的點序號

5.7        else if isLeft then R ß pre關聯的點序號

5.8        else if next關聯的點在LRpre組成的三角形外接圓內 then

          L ß next關聯的點序號

5.9  else R ß pre關聯的點序號

6  initEdge(edgeLedgeRLR)

7  insertEdge(LedgeL)

   insertEdge(RedgeR)

initEdge(edgeL,edgeR,L,R)函數初始化兩個半邊節點edgeLedgeR,其中edgeL將來插入到L的邊鏈表中,使R成爲L的相鄰點(edgeL->mainNum ß L,edgeL->adhereNum ß R)edgeR則剛好相反。

insertEdge(number,edge)函數把半邊節點edge插入到序號爲number的點的邊鏈表中,由於每個點維護的一個循環邊鏈表是按照相鄰點的逆時針方向存儲的,爲了在每次插入後仍然保持這個特性,必須在插入前,先計算要插入的點到第一個點(MyNodel結構中的start序號所示,在第一次插入時賦值,以後就算此節點被刪除,也不改變,以作參考)的夾角,按照夾角的大小來判斷插入的地方(夾角有序排列即意味着那些相鄰點按照逆時針方向排列)

deleteEdge(edge)函數就是把半邊節點edge和它的對應半邊(twin域指向的半邊節點)刪除。

由於篇幅過長,對於算法的說明在此省略(如求凸包,BCT,UCT等)

發佈了50 篇原創文章 · 獲贊 1 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章