多邊形填充算法之掃描線填充算法
多邊形填充可以是凸多邊形、凹多邊形、或者是可以是帶孔的多邊形。掃描線填充算法是一種常用的填充算法。
1. 多邊形填充過程一般可以分為四個步驟
(1)求交:計算掃描線與多邊形各邊的交點;
(2)排序:把所有交點按照遞增的順序進行排序;
(3)交點配對:1與2, 3與4等配對處理,每對代表掃描線與多邊形的一個相交的區間;
(4)區間填充:把這些相交的區間內的像素設置成多邊形顏色,填充區間之外的像素設置背景色。
2. 需要解決的問題
(1)掃描線與多邊形相交時,交點的取舍問題;
(2)多邊形邊界的像素取舍問題。
3. 問題解決
(1) 掃描線交於多變型的頂點時,根據頂點的對應的兩條邊的另一個頂點的位置來判斷取舍。
① 如果另外兩個頂點都高於掃描線,則取這個頂點算取2次,即此頂點可以填充,已經作為填充區間;
② 如果另外兩個頂點都低於掃描線,則這個交點算取0個,即此頂點不進行填充;
③ 如果另外兩個頂點一個在掃描線之上,另一個在掃描線之下,則這個交點算取1次,需要與另一個交點進行配對組成填充區間。
(2) 多邊形填充區間的邊界取舍問題:遵循“左下閉,右上開”的原則,來避免填充區域擴大的問題。
即落在左下邊界的像素進行填充,而落在右上的像素不進行填充,簡單解釋就是,如果掃描線交點是1和9,則實際填充的區間是[1,9),即不包括x坐標是9的那個點。
具體實現時,對掃描線取左閉右開。
由以上兩個策略,綜合效果是實現“左下閉,右上開”。
4. 填充算法的4個中的問題
了解幾個“連貫性”的概念:
“邊的連貫性”:多邊形與掃描線相交的邊,在一定的范圍內,相交的邊保持一定的不變性,也可以理解為,當一條便於當前掃描新相交時,其也可能與下一條掃描線相交;
“掃描線的連貫性”:掃描線與多邊形相交的交點,由於其連貫性,新的交點序列與之前的交點序列(交點的排序)基本保持一致,最多有幾個個別的交點的位置需要調整,整體上都是按照交點X值得遞增的順序排列,在程序實現上,可以借助這個特定實現排序效率的提高;
“掃描區間的連貫性”:對確定好的掃描線的填充區間,即區間內的開始點X值到區間結束X值,同一區間上的像素填充顏色相同。可以直接繪制一條區間內的填充色的線段,提高渲染效率。
(1)求掃描線與多邊形的求交運算問題,如果掃描線分別對所有的邊進行求交判定,這樣處理效率非常低,其中大量的判定計算都是徒勞的;
為了提高求交運算的效率,設定“AET活性邊界表”。
“AET活性邊表”:把於掃描線相交的邊稱為活性邊,並把他們按照與掃描線交點的X坐標遞增的順序放在一個鏈表中,這樣的鏈表稱為“AET(Active Edge Table)活性邊表”。
活性編標的
(2)
5. 算法步驟
1 算法過程: 2 void polyfill (polygon, color) 3 int color;多邊形 polygon; 4 { 5 for (各條掃描線i ) 6 { 初始化新邊表頭指針NET [i]; 7 把y min = i 的邊放進邊表NET [i]; 8 } 9 y = 最低掃描線號; 10 初始化活性邊表AET為空; 11 for (各條掃描線i ) 12 { 把新邊表NET[i]中的邊結點用插入排序法插入AET表,使之按x坐標遞增順序排列; 13 遍歷AET表,把配對交點區間(左閉右開)上的象素(x, y), 14 用drawpixel (x, y, color) 改寫象素顏色值; 15 遍歷AET表,把ymax= i 的結點從AET表中刪除,並把ymax > i結點的x值遞增Dx; 16 若允許多邊形的邊自相交,則用冒泡排序法對AET表重新排序; 17 } 18 } /* polyfill */
注意問題
(1)初始化新邊表數組時,各個數據項中的節點按照X遞增的順序排列;
()
()把判定如有新的表插入時,則將新的列表中的節點,通過“插入排序”進行插入操作;
()
由以上
