如何在指定的輸出設備上根據坐標描述構造基本二維幾何圖形(點、直線、圓、橢圓、多邊形域、字符串及其相關屬性等)。
圖形生成的概念
圖形的生成:是在指定的輸出設備上,根據坐標描述構造二維幾何圖形。
圖形的掃描轉換:在光柵顯示器等數字設備上確定一個最佳逼近於圖形的象素集的過程。
直線段的掃描轉換
直線的繪制要求
(1)直線要直;
(2)直線的端點要准確,無定向性無斷裂;
(3)直線的亮度、色澤要均勻;
(4)畫線的速度要快;
(5)具有不同的色澤、亮度、線型等。
解決的問題:給定直線兩端點P0(x0,y0)和P1(x1,y1),畫出該直線。
逐點比較法:
數值微分法(DDA法):
增量算法
直觀、易實現
不利於用硬件實現
x(i+1) = x(i) + 1
y(i+1) = y(i) + k
中點Bresenhan算法:
算法原理:根據直線的斜率確定或選擇變量在x或y方向上每次遞增一個單位,而另一方向的增量為1或0,它取決於實際直線與相鄰象素點的距離,這一距離稱為誤差項。
中點Bresenham算法——算法步驟
輸入直線的兩端點P0(x0,y0)和P1(x1,y1)。
計算初始值△x、△y、D=△x-2△y、x=x0、y=y0。
繪制點(x,y)。判斷D的符號。若D<0,則(x,y)更新為(x+1,y+1),D更新為D+2△x-2△y;否則(x,y)更新為(x+1,y), D更新為D-2△y。
當直線沒有畫完時,重復上一步驟,否則結束。
改進的Bresenhan算法——算法步驟
1.輸入直線的兩端點P0(x0,y0)和P1(x1,y1)。
2.計算初始值△x、△y、e=-△x、x=x0、y=y0。
3.繪制點(x,y)。
4.e更新為e+2△y,判斷e的符號。若e>0,則(x,y)更新為(x+1,y+1),同時將e更新為e-2△x;否則(x,y)更新為(x+1,y)。
5.當直線沒有畫完時,重復步驟3和4。否則結束。
圓的掃描轉換
解決的問題:繪出圓心在原點,半徑為整數R的圓x2+y2=R2。
簡單方程產生圓弧:
算法原理:利用其函數方程,直接離散計算。
中點Bresenham畫圓——算法步驟
1.輸入圓的半徑R。
2.計算初始值d=1-R、x=0、y=R。
3.繪制點(x,y)及其在八分圓中的另外七個對稱點。
4.判斷d的符號。若d<0,則先將d更新為d+2x+3,再將(x,y)更新為(x+1,y);否則先將d更新為d+2(x-y)+5,再將(x,y)更新為(x+1,y-1)。
5.當x<y時,重復步驟3和4。否則結束。
多邊形的掃描轉換與區域填充:
多邊形的掃描轉換主要是通過確定穿越區域的掃描線的覆蓋區間來填充。
區域填充是從給定的位置開始塗描直到指定的邊界條件為止。
多邊形的掃描轉換:
頂點表示用多邊形的頂點序列來刻划多邊形。
點陣表示是用位於多邊形內的象素的集合來刻划多邊形。
掃描轉換多邊形:從多邊形的頂點信息出發,求出位於其內部的各個象素,並將其顏色值寫入幀緩存中相應單元的過程。
X-掃描線算法——原理
基本思想:按掃描線順序,計算掃描線與多邊形的相交區間,再用要求的顏色顯示這些區間的所有象素。
X-掃描線算法——算法步驟
1.確定多邊形所占有的最大掃描線數,得到多邊形頂點的最小和最大y值(ymin和ymax)。
2.從y=ymin到y=ymax,每次用一條掃描線進行填充。
3.對一條掃描線填充的過程可分為四個步驟:
求交;排序;交點配對;區間填色。
X-掃描線算法——取整規則
交點的取整規則:使生成的像素全部位於多邊形之內。(用於直線等圖元掃描轉換的四舍五入原則可能導致部分像素位於多邊形之外,從而不可用)。
假定非水平邊與掃描線y=e相交,交點的橫坐標為x,規則如下:
規則1:X為小數,即交點落於掃描線上兩個相鄰像素之間時:
交點位於左邊界之上,向右取整;
交點位於右邊界之上,向左取整;
規則2:邊界上象素的取舍問題,避免填充擴大化。規定落在右邊邊界上的像素不予填充。(具體實現時,只要對掃描線與多邊形的相交區間左閉右開)
規則3:當掃描線與多邊形頂點相交時,交點的取舍,保證交點正確配對。
解決方法:
當掃描線與多邊形的頂點相交時,
若共享頂點的兩條邊分別落在掃描線的兩邊,交點只算一個;
若共享頂點的兩條邊在掃描線的同一邊,這時交點作為零個或兩個。
實際處理:只要檢查頂點的兩條邊的另外兩個端點的Y值,兩個Y值中大於交點Y值的個數是0,1,2,來決定取0,1,2個交點。
改進的有效邊表算法:
改進原理:
處理一條掃描線時,僅對有效邊求交。
利用掃描線的連貫性。
利用多邊形邊的連貫性。
改進的有效邊表算法(Y連貫性算法)
有效邊(Active Edge):指與當前掃描線相交的多邊形的邊,也稱為活性邊。
有效邊表(Active Edge Table, AET):把有效邊按與掃描線交點x坐標遞增的順序存放在一個鏈表中,此鏈表稱為有效邊表。
有效邊表的每個結點:
x
ymax
1/k
next
改進的有效邊表算法——構造邊表
首先構造一個縱向鏈表,鏈表的長度為多邊形所占有的最大掃描線數,鏈表的每個結點,稱為一個桶,則對應多邊形覆蓋的每一條掃描線
。
將每條邊的信息鏈入與該邊最小y坐標(ymin )相對應的桶處。也就是說,若某邊的較低端點為ymin,則該邊就放在相應的掃描線桶中。
每條邊的數據形成一個結點,內容包括:該掃描線與該邊的初始交點x(即較低端點的x值),1/k,以及該邊的最大y值ymax。
x|ymin
ymax
1/k
NEXT
同一桶中若干條邊按X|ymin由小到大排序,若X|ymax 相等,則按照1/k由小到大排序。
改進的有效邊表算法——算法步驟
(1)初始化:構造邊表,AET表置空;
(2)將第一個不空的ET表中的邊與AET表合並;
(3)由AET表中取出交點對進行填充。填充之后刪除y=ymax的邊;
(4)yi+1=yi+1,根據xi+1=xi+1/k計算並修改AET表,同時合並ET表中y=yi+1桶中的邊,按次序插入到AET表中,形成新的AET表;
(5)AET表不為空則轉(3),否則結束。
邊緣填充算法:
基本思想:按任意順序處理多邊形的每條邊。處理時,先求出該邊與掃描線的交點,再對掃描線上交點右方的所有象素取反。
算法簡單,但對於復雜圖型,每一象素可能被訪問多次
柵欄填充算法:
柵欄指的是一條過多邊形頂點且與掃描線垂直的直線。它把多邊形分為兩半。
基本思想:按任意順序處理多邊形的每一條邊,但處理每條邊與掃描線的交點時,將交點與柵欄之間的象素取反。
這種算法盡管減少了被重復訪問象素的數目,但仍有一些象素被重復訪問。
邊標志算法:
基本思想:先用特殊的顏色在幀緩存中將多邊形的邊界勾畫出來,然后將着色的象素點依x坐標遞增的順序配對,再把每一對象素構成的區間置為填充色。
分為兩個步驟:打標記;填充。
當用軟件實現本算法時,速度與改進的有效邊表算法相當,但本算法用硬件實現后速度會有很大提高。
區域填充
基本概念:
區域填充是指從區域內的某一個象素點(種子點)開始,由內向外將填充色擴展到整個區域內的過程。
區域是指已經表示成點陣形式的填充圖形,它是相互連通的一組像素的集合。
區域的表示方法:
邊界表示法:把位於給定區域的邊界上的象素一一列舉出來的方法。
邊界表示法中,由於邊界由特殊顏色指定,填充算法可以逐個象素地向外處理,直到遇到邊界顏色為止,這種方法稱為邊界填充算法(Boundary-fill Algorithm)。
內點表示法:枚舉出給定區域內所有象素的表示方法。以內點表示法為基礎的區域填充算法稱為泛填充算法(Flood-fill Algorithm)。
區域的分類:
4-連通區域:從區域上的一點出發,通過訪問已知點的4-鄰接點,在不越出區域的前提下,遍歷區域內的所有象素點。
8-連通區域:從區域上的一點出發,通過訪問已知點的8-鄰接點,在不越出區域的前提下,遍歷區域內的所有象素點。
4連通與8連通區域的區別:
連通性: 4連通可看作8連通區域,但對邊界有要求。
對邊界的要求。
區域填充算法:
區域填充算法(邊界填充算法和泛填充算法)是根據區域內的一個已知象素點(種子點)出發,找到區域內其他象素點的過程,所以把這一類算法也成為種子填充算法。
算法的輸入:種子點坐標(x,y),填充色以及邊界顏色。
利用堆棧實現簡單的種子填充算法
算法從種子點開始檢測相鄰位置是否是邊界顏色,若不是就用填充色着色,並檢測該像素點的相鄰位置,直到檢測完區域邊界顏色范圍內的所有像素為止。
棧結構實現4-連通邊界填充算法的算法步驟為:
種子象素入棧;當棧非空時重復執行如下三步操作:
(a)棧頂象素出棧;
(b)將出棧象素置成填充色;
(c)檢查出棧象素的4-鄰接點,若其中某個象素點不是邊界色且未置成多邊形色,則把該象素入棧。
棧結構實現8-連通邊界填充算法的算法步驟為:
種子象素入棧;當棧非空時重復執行如下三步操作:
(a)棧頂象素出棧;
(b)將出棧象素置成填充色;
(c)檢查出棧象素的8-鄰接點,若其中某個像素點不是邊界色且未置成多邊形色,則把該像素入棧。可以用於填充帶有內孔的平面區域。
把太多的像素壓入堆棧,降低了效率,同時需要較大的存儲空間。
遞歸執行,算法簡單,但效率不高,區域內每一像素都引起一次遞歸,進/出棧費時費內存。
通過沿掃描線填充水平象素段,來代替處理4-鄰接點和8-鄰接點。
掃描線種子填充算法:掃描線通過在任意不間斷掃描線區間中只取一個種子像素的方法使堆棧的尺寸極小化。不間斷區間是指在一條掃描線上的一組相鄰像素。
基本過程:當給定種子點時,首先填充種子點所在的掃描線上的位於給定區域的一個區段,然后確定與這一區段相通的上下兩條掃描線上位於給定區域內的區段,並依次保存下來。反復這個過程,直到填充結束。
區域填充算法——泛填充算法
算法的輸入:種子點坐標(x,y),填充色和內部點的顏色。
算法原理:算法從指定的種子(x,y)開始,用所希望的填充顏色賦給所有當前為給定內部顏色的象素點。種子象素入棧;棧非空時重復執行如下三步操作:
(1)棧頂象素出棧;
(2)將出棧象素置成填充色;
(3)檢查出棧象素的8-鄰接點,若其中某個象素點不是給定內部點的顏色且未置成新的填充色,則把該象素入棧。
當以邊界表示時,4-連通邊界填充算法只能填充4-連通區域,8-連通邊界填充算法也只能填充8-連通區域。
當以內點表示時,8-連通泛填充算法可以填充8-連通區域也可以填充4-連通區域,當然4-連通泛填充算法還是只能填充4-連通區域。