关闭

掃描多邊形填充算法

标签: 算法c
1178人阅读 评论(0) 收藏 举报
分类:

http://www.cnblogs.com/carekee/articles/1769714.html

多邊形填充,就是把多邊形所佔據的柵格象素賦予指定的顏色值。要完成這個任務,一個首要的問題就是求出多邊形所佔據的柵格象素,判斷一個網格在多邊形內還是多邊形外,在多邊形內的象素,則賦予指定的顏色值,多邊形外的象素,則不賦予指定的顏色值,具體該如何判斷象素是否在多邊形內呢?這裡我們采用掃描線多邊形填充算法

掃描多邊形填充算法的基本原理——在直角坐標系中,假設有一條從左至右的掃描線穿過多邊形,從左至右開始計數,與多邊形交點為奇數時,開始進入多邊形,與多邊形交點為偶數時,走出多邊形。這樣在這相鄰配對的奇偶交點間的所有象素都在多邊形內。如圖,奇數交點ac,都是進入多邊形,偶數交點bd都是走出多邊形,相鄰的奇偶交點配對,ab之間,cd之間的象素都在多邊形內,可見一條掃描線上,與多邊形交點個數需要為偶數。依據這樣的思路,掃描線從上到下,從左到右依次掃過多邊形即可求得多邊形所佔據的象素。(注意退化情況的處理,也就是掃描線剛好經過頂點或者多邊形的邊本身就是水平的情況)


具體實現——首先,求多邊形最上,最下的行號,以便於確定掃描線的行數,這個可以根據多邊形的MBR求得;其次,確定一條掃描線上,與多邊形的交點,保證交點個數為偶數,並對這些交點按列號從小到大排列;最後,掃描轉換,掃描線從上到下,每條掃描線從左到右,對這些排序好的奇偶點配對連線。所采用的數據結構類似於「鋸齒狀的二維數組」,第一維代表行號,第二維代表一行中的交點。為了實現以上的步驟,需要對多邊形邊界進行柵格化,確定邊界所經過的柵格,並把這些存儲為「鋸齒狀的二維數組」(柵格化方法有:數值微分法,Bresenham算法,柵格中心線求交法)。退化情況的處理:

一、邊線端點的處理。比較此端點與它相鄰的前後兩端點所在掃描線的行號,設此端點的行號為h0,前一端點的行號為h1,後一端點的行號為h2。

1)        h0>h1 and h0>h2,如圖,點A、C、F,這些端點的柵格點不予以記錄,即掃描線經過該點,計交點為0。

2)        h0<h1 and h0<h2,如圖,點B、E、G,這些端點的柵格點記錄兩次,即掃描線經過該點,計交點為2。

3)        h0<h1 and h0>h2 or h0>h1 and h0<h2,如圖,點D,H,這些端點的柵格點記錄一次,即掃描線經過該點,計交點為1。


二、水平線的處理。多邊形邊線段,掃描出來為一橫線,即一條線段從頭到尾都佔據一行柵格。理論上,這種情況與掃描線有無數個交點,為了保持一行中交點個數為偶數,判斷當前橫線段與前後相鄰兩條線段的位置關系,同時先柵格化此橫線,作以下規定。

1)        前後相鄰兩線段位於此橫線段的異側,如圖,橫線段AB,前後兩線段AIBC位於橫線段AB的異側,則與此橫線段交點計為1,記錄A點或者B點,均可。

2)        前後相鄰兩線段位於此橫線段的同側,如圖,橫線段GF,前後兩線段GHFE位於橫線段GF的同側,則與此橫線段交點計為0,不記錄任何交點。


這種判斷的思想是這樣的:基於動態的思想,橫線AB,假設A和B兩點相互靠近,最終成為一點,假設為A『,根據端點處理的方法,A』介於前後兩點I、C之間,應計交點一個,而對於橫線GF,一樣的道理,GF相互靠近最終成為一點,假設為F『,根據端點處理的方法,F』大於前後兩點E、H,應計交點0。這種判斷可以有效處理橫線,但又帶來一個新的問題,如果相鄰前或者後兩線段也是同此橫線一樣,也是在這一行水平,這樣就要遞推到更前或者更後的線段,直到找出以上判斷的條件。


如圖,判斷線段AB,需要找到前一條線段AJ,後一條線段BC,由於BC與AB都是水平的,需要找再下一條CD,得到AJ、CD位於水平線的異側,則計交點為1。判斷線段GH,前後兩線段GF、HI都是水平的,需要分別尋找更前,、更後的線段FE、IJ,一直遞歸下去,直到確定判斷條件。如果覺得這種情況比較麻煩,在程序端點循環的時候,找到第一段不是橫線的起點開始循環,這樣,只要判斷,橫線後面條線段的情況,直到確定判斷條件即可。


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:945066次
    • 积分:10978
    • 等级:
    • 排名:第1520名
    • 原创:11篇
    • 转载:534篇
    • 译文:0篇
    • 评论:3条
    最新评论