掃描線法填充多邊形

原理

如下圖所示多邊形:

簡述

直線y=1,2,3……8順序掃描多邊形,以直線y=3爲例,它與多邊形的邊有4個交點,將這4個交點的x座標保存下來,兩兩之間畫線,也就是(A,B)(C,D)之間畫線。對於每一個y都是兩兩之間畫線。現在考慮直線y=2,它與多邊形有3個交點,很顯然是F,G之間畫線,那麼p1怎麼處理呢?可以觀察到p1是多邊形邊的一個端點,是兩條邊的交點,因此,可以選擇將p1看作兩個點存儲,這樣(p1,p1)之間畫線,就是描一個點。或者不存儲p1,只在(F,G)之間畫線。我採用的是不存儲p1。

活性邊表

具體每一條掃描線對應的座標存儲在活性邊表Aet中,每一條掃描線對應一個鏈表,鏈表中的節點類型爲
x dx ymax next
其中,x爲交點的x座標,dx爲相交直線的x方向增量(x2-x1)/(y2-y1),ymax爲直線可以到達的最大y值。由於我採用的是當掃描線與邊的端點相交時不存儲此交點,所以,掃描線y=1的Aet中沒有存儲座標,y=2中不存儲p1,只存儲F,G的x座標以及F,G所在直線的斜率倒數。

新邊表

新邊表Net用來記錄y爲多少時與新的邊相交,每一條掃描線也對應一個鏈表,結點類型和Net中的結點類型相同。
如圖中的新邊表中,y=1應該記錄  (p2,p3),(p4,p3)兩條直線的信息;y=2應該記錄(p1,p6),(p1,p2)兩條直線的信息,y=6記錄(p4,p5)一條邊的信息,y=7記錄(p6,p5)一條邊的信息。

掃描過程

1、建立新邊表(對於斜率爲0的直線不計入新邊表);
2、建立y=i對應的活性邊表:
      檢查y=i對應的新邊表中是否有結點,若有,則將這些結點加入活性邊表 ;
     檢查y=i-1對應的活性邊表,對於ymax=i的結點,忽略不計(也可以記錄,根據個人選擇) ,如果ymax<i,則將結      點中x=x+dx後,把結點加入y=i對應的活性邊表;
     將y=i對應的活性邊表按照x遞增(或遞減)的順序排序。
3、依次掃描活性邊表,兩兩之間畫線。

實例

對於上圖來說,新邊表如下:
 y=1
11 -2 4 --> 11 0 6
y=2
2 1.5 4 --> 2 0 7
y=3  NULL
y=4  NULL
y=5  NULL
y=6
11 -3 8
y=7
2 3 8
y=8  NULL

活性邊表如下:
y=1  加入新邊表的結點
11 -2 4 --〉 11 0 6
y=2  加入新邊表中的節點,y=1中的結點修改後加入(我這裏沒有排序,實際上應該排序的)
2 1.5 4 --〉 2 0 7 --〉 9 -2 4 --〉 11 0 6
y=3    y=2對應的活性邊表中的結點修改後加入
3.5 1.5 4 --〉 2 0 7 --〉 7 -2 4 --〉 11 0 6
y=4  
2 0 7 --〉
11 0 6
y=5
2 0 7 --〉 11 0 6
y=6
2 0 7 --〉 11 -3 8
y=7
2 3 8 --〉 8 -3 8
y=8   NULL

程序實現中涉及較多對鏈表的操作,包括構建、排序,會寫在以下文章中。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章