大連理工大學選修課——圖形學:第三四章 基本圖形生成算法

第三四章 基本圖形生成算法

圖形生成

概念:如何在指定的輸出設備上,根據坐標描述,構造基本二維幾何圖形

基本二維幾何圖形:點、直線、圓、多邊形域、字符串及相關屬性等。

圖形生成的概念

是在指定的輸出設備上,根據坐標描述構造二維幾何圖形。

圖形的掃描轉換:在光柵顯示器等數字設備上,確定一個醉駕逼近于圖形的像素集的過程。

光柵化

光柵就是德語中屏幕的意思,光柵化就是把圖形畫在屏幕上的過程,即將幾何圖形轉化為像素化圖像的過程。

基本過程:

  1. 確定最佳逼近圖形的像素集合。
  2. 用圖形的顏色或其它屬性,按照掃描順序,對像素進行某種寫操作,完成圖形在屏幕上的顯示。

直線段和圓的光柵化

直線段和圓是最基本的圖形元素,包括以下幾種算法:

直線光柵化算法:DDA算法、Bresenham算法

圓光柵化算法:Bresenham畫圓算法、中點算法、中點整數算法、中點整數優化算法。

直線的光柵化算法

要求:直、精確的起始點、亮度顏色均勻且沿直線不變,與直線長度、方向無關、快。

DDA算法

David F.Rogers的描述(適用于所有象限)

步驟如下:

  1. 如果已知第 i i i點的坐標,利用步長 S t e p X StepX StepX S t e p Y StepY StepY,得到第 i + 1 i+1 i+1點的坐標, i + 1 i+1 i+1點的坐標為:

x i + 1 = x i + S t e p X y i + 1 = y i + K ? S t e p X x_{i+1}=x_i+StepX\quad y_{i+1}=y_i+K\cdot StepX xi+1?=xi?+StepXyi+1?=yi?+K?StepX

  1. 如圖所示, K < 1 , S t e p X = 1 , S t e p Y = k K<1,StepX=1,StepY=k K<1,StepX=1StepY=k,將直線上每個點的坐標四舍五入,得到光柵點的位置:

    在這里插入圖片描述

James D.Foley的描述(只適用于第一象限,且K<1)

令:

k = y 2 ? y 1 x 2 ? x 1 k=\frac{y_2-y_1}{x_2-x_1} k=x2??x1?y2??y1??

有:

y i + 1 = y i + k ? S t e p X y_{i+1}=y_i+k\cdot StepX yi+1?=yi?+k?StepX

0 < k < 1 0<k<1 0<k<1,則 △ x > △ y \triangle x>\triangle y x>y

因為光柵單位為1,每次 x x x方向增加1,y方向增加k,得到下一個直線點。

現有算法描述分析

Rogers:

采用 x i + 1 = x i + S t e p X y i + 1 = y i + K ? S t e p X x_{i+1}=x_i+StepX\quad y_{i+1}=y_i+K\cdot StepX xi+1?=xi?+StepXyi+1?=yi?+K?StepX,逼近點并不是直線最好的逼近

D.Foley:可能引起累積誤差

未分析直線端點不在像素點的情況,且只給出 0 ° 0\degree - 45 ° 45\degree 45°的第一卦限的情況。

每次步長為一個單位,減少累積誤差。

本教程描述——任意方向插補算法

if (fabs(dy)<fabs(dx)) {     //X方向長 , 斜率 <=1Length=abs(Round(xe)-Round(xs));Flag=1; //最大的插補長度和方向標記ix= Round(xs); //初始 X點idx=isign(dx); //X方向單位增量y= ys+dy/dx*((float)(ix)-xs); //初始 Y點修正dy=dy/fabs(dx); //Y方向斜率增量
}else { // Y方向長 , 斜率 >1Length=abs(Round(ye)-Round(ys));Flag=0;iy= Round(ys); //初始 Y點idy=isign(dy); //Y方向單位增量x= xs+dx/dy*((float)(iy)-ys); //初始 X點修正dx=dx/fabs(dy); //X方向斜率增量
}

在這里插入圖片描述

Bresenham算法

Bresenham算法:

從另一個角度看直線光柵化顯示算法的原理:由直線的斜率確定選擇在 x x x方向或 y y y方向上每次遞增1個單位,另一變量遞增量為0或1,取決于實際直線與網格點的距離,四舍五入。

  1. 基本原理

    假定直線斜率k在 0 0 0- 1 1 1之間,此時, x x x方向每次遞增一個單位,決定 y y y方向每次遞增0或1。

    (斜率大于1,y每次遞增1,小于1,x每次遞增1)

    假設:當前點為 ( x i , y ) (x_i,y) (xi?,y),當前光柵點為 ( x i , y i ) (x_i,y_i) (xi?,yi?)

    則下一點為: ( x i + 1 , y + k ) , k ∈ { 0 , 1 } (x_i+1,y+k),k\in\{0,1\} (xi?+1,y+k),k{0,1}

    在這里插入圖片描述

    記直線與它垂直方向最近的下光柵點誤差為 d d d

    d < 0.5 d<0.5 d<0.5:下一像素點為 ( x i + 1 , y i ) (x_i+1,y_i) (xi?+1,yi?)

    d > 0.5 d>0.5 d>0.5:下一像素點為 ( x i + 1 , y i + 1 ) (x_i+1,y_i+1) (xi?+1,yi?+1)

在這里插入圖片描述

  1. 對bresenham的簡化

    e = d ? 0.5 e=d-0.5 e=d?0.5,關于d的判別式和初值可簡化成:

    e < 0 e<0 e<0:取 ( x i + 1 , y i ) (x_i+1,y_i) (xi?+1,yi?)

    e > 0 e>0 e>0:取 ( x i + 1 , y i + 1 ) (x_i+1,y_i+1) (xi?+1,yi?+1) e = e ? 1 e=e-1 e=e?1

  2. 整數Bresenham算法

    上述Bresenham算法在計算直線斜率和誤差項時需要浮點運算和除法,采用整數算術運算和避免除法可以加快算法速度。

    只需作以下變換:

    初值:

    E r r o r = △ y / △ x ? 0.5 Error=\triangle y/\triangle x-0.5 Error=y/△x?0.5

    經過簡單變換:

    N E r r o r = 2 ? E r r o r ? △ x = 2 △ y ? △ x NError=2\cdot Error\cdot\triangle x=2\triangle y-\triangle x NError=2?Error?x=2△y?x

    便得到了整數算法。

  3. 一般Bresenham算法

    為了使第一卦限的Bresenham算法適用于一般直線,進行如下改造:

    1. 當直線斜率 ∣ k ∣ > 1 |k|>1 k>1時,改為y的增量總為1,判斷 x x x是否需要增加1
    2. x x x y y y的增量可能是1或-1,視直線所在象限決定。

圓光柵化算法

簡單方程方法

圓的極坐標方程為:

x = R cos ? θ y = R sin ? θ x=R\cos\theta\\ y=R\sin\theta x=Rcosθy=Rsinθ

每次給 θ \theta θ θ \theta θ θ i + 1 = θ i + △ θ \theta_{i+1}=\theta_i+\triangle\theta θi+1?=θi?+θ

那么:

x i + 1 = r o u n d ( R cos ? θ i + 1 ) y i + 1 = r o u n d ( R sin ? θ i + 1 ) x_{i+1}=round(R\cos\theta_{i+1})\\ y_{i+1}=round(R\sin\theta_{i+1}) xi+1?=round(Rcosθi+1?)yi+1?=round(Rsinθi+1?)

利用圓的八方對稱畫圓

Bresenham畫圓算法

以圓心為坐標原點,建立局部坐標系

先考慮第一象限的八分之一圓弧:

P i ? 1 ( x i ? 1 , y i ? 1 ) P_{i-1}(x_{i-1},y_{i-1}) Pi?1?(xi?1?,yi?1?)為已確定的逼近像素點

x i = x i ? 1 + 1 x_i=x_{i-1}+1 xi?=xi?1?+1時,要決定 y i y_i yi?的取值

E ( R 2 , R 2 ) E(\frac{R}{\sqrt2},\frac{R}{\sqrt2}) E(2 ?R?,2 ?R?)

D ( S i ) = [ ( x i ? 1 + 1 ) 2 + y i ? 1 2 ] ? R 2 D ( T i ) = [ ( x i ? 1 + 1 ) 2 + ( y i ? 1 ? 1 ) 2 ] ? R 2 D(S_i)=[(x_{i-1}+1)^2+y^2_{i-1}]-R^2\\ D(T_i)=[(x_{i-1}+1)^2+(y_{i-1}-1)^2]-R^2 D(Si?)=[(xi?1?+1)2+yi?12?]?R2D(Ti?)=[(xi?1?+1)2+(yi?1??1)2]?R2

∣ D ( S i ) ∣ ≥ ∣ D ( T I ) ∣ |D(S_i)|\geq|D(T_I)| D(Si?)D(TI?),則 T i T_i Ti? S i S_i Si?更接近實際的圓弧, 應選 T i T_i Ti?
反之,選擇 S i S_i Si?

d i = ∣ D ( S i ) ∣ ? ∣ D ( T i ) ∣ d_i=|D(S_i)|-|D(T_i)| di?=D(Si?)?D(Ti?)

于是, d i ≥ 0 d_i\geq0 di?0時,選 T i T_i Ti?,反之,選擇 S i S_i Si?

在這里插入圖片描述

分析情況ABCDE,可以將 d i d_i di?改寫為:

d i = D ( S i ) + D ( T i ) = [ ( x i ? 1 + 1 ) 2 + y i ? 1 2 ] ? R 2 + [ ( x i ? 1 + 1 ) 2 + ( y i ? 1 ? 1 ) 2 ] ? R 2 \begin{align} d_i=&D(S_i)+D(T_i)\\ =&[(x_{i-1}+1)^2+y^2_{i-1}]-R^2+[(x_{i-1}+1)^2+(y_{i-1}-1)^2]-R^2\\ \end{align} di?==?D(Si?)+D(Ti?)[(xi?1?+1)2+yi?12?]?R2+[(xi?1?+1)2+(yi?1??1)2]?R2??

i + 1 i+1 i+1代替上式中的 i i i,得:

d i + 1 = [ ( x i + 1 ) 2 + y i 2 ] ? R 2 + [ ( x i + 1 ) 2 + ( y i ? 1 ) 2 ] ? R 2 \begin{align} d_{i+1}=&[(x_{i}+1)^2+y^2_{i}]-R^2+[(x_{i}+1)^2+(y_{i}-1)^2]-R^2\\ \end{align} di+1?=?[(xi?+1)2+yi2?]?R2+[(xi?+1)2+(yi??1)2]?R2??

d i + 1 ? d i d_{i+1}-d_i di+1??di?,得:

d i + 1 ? d i = 2 [ ( x i + 1 ) 2 ? ( x i ? 1 + 1 ) 2 ] + ( y i 2 ? y i ? 1 2 ) + ( y i ? 1 ) 2 ? ( y i ? 1 ? 1 ) 2 d_{i+1}-d_i=2[(x_i+1)^2-(x_{i-1}+1)^2]+(y_i^2-y_{i-1}^2)+(y_i-1)^2-(y_{i-1}-1)^2 di+1??di?=2[(xi?+1)2?(xi?1?+1)2]+(yi2??yi?12?)+(yi??1)2?(yi?1??1)2

改進:

d i ≥ 0 , d_i\ge0, di?0, T i T_i Ti?,此時:

x i = x i ? 1 + 1 y i = y i ? 1 ? 1 d i + 1 = d i + 4 ( x i ? 1 ? y i ? 1 ) + 10 x_i=x_{i-1}+1\\ y_i=y_{i-1}-1\\ d_{i+1}=d_i+4(x_{i-1}-y_{i-1})+10 xi?=xi?1?+1yi?=yi?1??1di+1?=di?+4(xi?1??yi?1?)+10

反之,選 S i S_i Si?,此時

x i = x i ? 1 + 1 y i = y i ? 1 d i + 1 = d i + 4 x i ? 1 + 6 x_i=x_{i-1}+1\\ y_i=y_{i-1}\\ d_{i+1}=d_i+4x_{i-1}+6 xi?=xi?1?+1yi?=yi?1?di+1?=di?+4xi?1?+6

d i d_i di?的初值 d 1 d_1 d1?可以由 ( 1 ) (1) (1)求出,將 i = 1 , x 0 = 0 , y 0 = R i=1,x_0=0,y_0=R i=1,x0?=0,y0?=R帶入,得:

d 1 = 3 ? 2 R d_1=3-2R d1?=3?2R

顯然,改進方法的計算量更小,效率高。

中點圓算法

d d d為點 p ( x , y ) p(x,y) p(x,y)到圓心的距離,有:

d = F ( x , y ) = x 2 + y 2 ? R 2 d=F(x,y)=x^2+y^2-R^2 d=F(x,y)=x2+y2?R2

以圓的下 2個可選像素 中點的函數值 d的符號 決定選擇 2個可選像素 T和 B中哪一個更接近圓而作為圓的顯示點 :

在這里插入圖片描述

d M = F ( x M , y M ) = F ( x p + 1 , y p ? 0.5 ) = ( x p + 1 ) 2 + ( y p ? 0.5 ) 2 ? R 2 d_M=F(x_M,y_M)=F(x_p+1,y_p-0.5)=(x_p+1)^2+(y_p-0.5)^2-R^2 dM?=F(xM?,yM?)=F(xp?+1,yp??0.5)=(xp?+1)2+(yp??0.5)2?R2

如果 d M ≤ 0 d_M\le0 dM?0,表示下一個中點M在圓內,用T逼近,得:

d M T = F ( x M T , y M T ) = F ( x p + 2 , y p ? 0.5 ) = ( x p + 2 ) 2 + ( y p ? 0.5 ) 2 ? R 2 △ d M T = d M T ? d M = 2 x p + 3 d_{MT}=F(x_{MT},y_{MT})=F(x_p+2,y_p-0.5)=(x_p+2)^2+(y_p-0.5)^2-R^2\\ \triangle d_{MT}=d_{MT}-d_{M}=2x_p+3 dMT?=F(xMT?,yMT?)=F(xp?+2,yp??0.5)=(xp?+2)2+(yp??0.5)2?R2dMT?=dMT??dM?=2xp?+3

反之,表示下一中點M在園外,用B逼近,得:

d M B = F ( x M B , y M B ) = F ( x p + 2 , y p ? 1.5 ) △ d M B = d M B ? d M = 2 x p ? 2 y p + 5 d_{MB}=F(x_{MB},y_{MB})=F(x_p+2,y_p-1.5)\\ \triangle d_{MB}=d_{MB}-d_{M}=2x_p-2y_p+5 dMB?=F(xMB?,yMB?)=F(xp?+2,yp??1.5)dMB?=dMB??dM?=2xp??2yp?+5

綜上,中點圓算法為:

根據中點d的值,決定顯示的光柵點,更新 △ d \triangle d d ( △ d M T 或 △ M B ) (\triangle d_{MT}或\triangle_{MB}) (dMT?MB?),更新d。

初值

x 0 = 0 , y 0 = R x_0=0,y_0=R x0?=0,y0?=R
x M 0 = 0 + 1 = 1 , y M 0 = R ? 0.5 x_{M0}=0+1=1,y_{M0}=R-0.5 xM0?=0+1=1,yM0?=R?0.5
d M 0 = F ( x M 0 , y M 0 ) = 1.25 ? R d_{M0}=F(x_{M0},y_{M0})=1.25-R dM0?=F(xM0?,yM0?)=1.25?R

中點圓整數算法

為了將其改造為整數計算,定義新變量: D = d ? 0.25 D=d-0.25 D=d?0.25
判別式 d < 0 d<0 d<0等價于 D < ? 0.25 D<-0.25 D<?0.25
在D為整數的情況下, D < ? 0.25 D<-0.25 D<?0.25等價于 D < 0 D<0 D<0
仍將D寫為d(新的初值 d = 1 ? r a d i u s d=1-radius d=1?radius),可得到中點圓整數算法

橢圓光柵化算法

設橢圓方程為:

F ( x , y ) = b 2 x 2 + a 2 y 2 ? a 2 b 2 = 0 F(x,y)=b^2x^2+a^2y^2-a^2b^2=0 F(x,y)=b2x2+a2y2?a2b2=0

該橢圓上一點 ( x , y ) (x,y) (x,y)處的法向量為:

N ( x , y ) = ? F ? x i + ? F ? y j = 2 b 2 x i + 2 a 2 y j N(x,y)=\frac{\partial F}{\partial x}i+\frac{\partial F}{\partial y}j=2b^2xi+2a^2yj N(x,y)=?x?F?i+?y?F?j=2b2xi+2a2yj

在這里插入圖片描述

在上半部分,法向量y的分量更大而在下部分, 法向量的x分量更大, 因而, 在上部分若當前最佳逼近理想橢圓弧的像素(xP,yP)滿足下列不等式:

b 2 ( x p + 1 ) < a 2 ( y p ? 0.5 ) b^2(x_p+1)<a^2(y_p-0.5) b2(xp?+1)<a2(yp??0.5)

在上半部分,假設橫坐標為 x p x_p xp?的像素中,與橢圓弧更接近的點是 ( x p , y p ) (x_p,y_p) (xp?,yp?),那么下一對候選像素的中點為 ( x p + 1 , y p ? 0.5 ) (x_p+1,y_p-0.5) (xp?+1,yp??0.5),判別式為:

d 1 = F ( x p + 1 , y p ? 0.5 ) = b 2 ( x p + 1 ) 2 + a 2 ( y p ? 0.5 ) 2 ? a 2 b 2 d_1=F(x_p+1,y_p-0.5)=b^2(x_p+1)^2+a^2(y_p-0.5)^2-a^2b^2 d1?=F(xp?+1,yp??0.5)=b2(xp?+1)2+a2(yp??0.5)2?a2b2

d 1 < 0 d_1<0 d1?<0,中點在橢圓內,則取正右方像素,判別式更新:

d 1 , = F ( x p + 2 , y p ? 0.5 ) d_1^,=F(x_p+2,y_p-0.5) d1,?=F(xp?+2,yp??0.5)

d 1 ≥ 0 d_1\ge0 d1?0,中點在橢圓外,此時取右下方像素,更新判別式:

d 1 ′ = F ( x p + 2 , y p ? 1.5 ) d_1'=F(x_p+2,y_p-1.5) d1?=F(xp?+2,yp??1.5)

由于弧的起點為 ( 0 , b ) (0,b) (0,b),第一中點為 ( 1 , b ? 0.5 ) (1,b-0.5) (1,b?0.5),對應判別式為:

d 10 = F ( 1 , b ? 0.5 ) d_{10}=F(1,b-0.5) d10?=F(1,b?0.5)

**在下部分,**改為從正下方和右下方兩個像素選擇下一像素,計算與上半部分類似。

基本多邊形掃描轉換與區域填充

多邊形的掃描轉換,主要通過確定穿越區域的掃描線覆蓋區間來填充。

區域填充是從給定的位置開始涂描,直到指定的邊界條件為止。

多邊形的掃描轉換

頂點表示:用多邊形的頂點序列刻畫多邊形。

點陣表示:用位于多邊形內的像素集合來刻畫多邊形。

掃描轉換多邊形:從多邊形的頂點信息出發,求出位于其內部的各個像素,并將顏色值寫入幀緩存中相應單元的過程。

基本問題有:

  1. 如何判斷一個點是否位于多邊形區域內?

    點在多邊形內的包含性檢驗方法:檢驗夾角之和、射線法檢驗交點數。

轉角法:若夾角和為0,則點 p p p在多邊形外;若夾角和為360,則點 p p p在多邊形內。

在這里插入圖片描述

射線法:交點數為偶數,點在多邊形外;交點數為奇數,點在多邊形之內。

在這里插入圖片描述

  1. 逐點測試效率太低

采用包圍盒法:對凸多邊形效果好,但凹多邊形效率仍然低下。

在這里插入圖片描述

掃描線填充算法:

掃描線填充算法:按掃描線順序,測試點的連貫性。

種子填充算法:從內部一個種子點出發,測試點的連貫性。

X-掃描線算法

基本思想:

按掃描線順序,計算掃描線與多邊形的相交區間;再用要求的顏色顯示區間的所有像素。

在這里插入圖片描述

算法步驟:

  1. 確定多邊形所占有的最大掃描線數,得到多邊形頂點的最小、最大 y y y ( y m i n 和 y m a x ) (y_{min}和y_{max}) (ymin?ymax?)
  2. y = y m i n y=y_{min} y=ymin? y = y m a x y=y_{max} y=ymax?,每次用一條掃描線進行填充。
  3. 對一條掃描線填充的過程分為四個步驟:求交、排序、交點配對、區間填色。

取整規則

交點的取整規則:使生成的像素全部位于多邊形之內。

為什么不采用四舍五入的規則?四舍五入可能導致部分像素位于多邊形之外,從而不可用。

假定非水平邊和掃描線y=e相交,交點橫坐標為 x x x,規則如下:

  1. x x x為小數,即交點落在掃描線上兩個相鄰像素間時:

    1. 交點位于左邊界上,向右取整。

    2. 交點位于右邊界上,向左取整。

      在這里插入圖片描述

  2. 邊界上像素的取舍:為了避免填充擴大化,規定落在右邊邊界上的像素不予填充。

    • 具體實現時,對掃描線與多邊形相交區間左閉右開。

      在這里插入圖片描述

  3. 當掃描線與多邊形頂點相交時:交點的取舍,保證交點正確配對。

    • 交點配對:當掃描線與多邊形的頂點相交時:

      • 若共享頂點的兩條邊落在掃描線兩邊,交點只算一個。
      • 若共享頂點的兩條邊落在掃描線同一邊,交點作為零或兩個。
    • 實際處理中,只要檢查頂點的兩條邊的另外兩個端點的Y值,兩個Y值中,大于交點Y值的個數為0\1\2,來決定取0\1\2個交點。

      在這里插入圖片描述

改進的有效邊表算法(Y連貫性算法)

改進原理:

  • 處理一條掃描線時,僅對有效邊求交。
  • 利用掃描線的連貫性。
  • 利用多邊形邊的連貫性。

有效邊:與當前掃描線相交的多邊形的邊,也稱為活性邊。
有效邊表:把有效邊按與掃描線交點x坐標遞增的順序存放在一個鏈表中,此鏈表稱為有效邊表。

有效邊表中,每個結點的存儲方式:

x ∣ y m i n y m a x 1 k n e x t x|_{y_{min}}\quad y_{max}\quad \frac{1}{k}\quad next xymin??ymax?k1?next

構造邊表:

  1. 首先構造一個縱向鏈表,鏈表的長度為多邊形所占有的最大掃描線數,鏈表的每個結點,稱為一個桶,對應多邊形覆蓋的每一條掃描線。

  2. 將每條邊的信息鏈入與該邊最小y坐標( y m i n y_{min} ymin? )相對應的桶處。
    (也就是說,若某邊的較低端點為 y m i n y_{min} ymin?,則該邊放在相應的掃描線桶中。)

  3. 每條數據邊形成一個結點,內容包括:

    1. 掃描線與該邊的初始交點x(較低端點的x值)
    2. 1 k \frac{1}{k} k1?
    3. 該邊的最大 y y y y m a x y_{max} ymax?
  4. 同一桶中,若干條邊按 x x x由小到大排序,若相等,按照 1 k \frac{1}{k} k1?由小到大排序。

    在這里插入圖片描述

在這里插入圖片描述

算法步驟:

  1. 初始化:構造邊表,AET表置空。
  2. 將第一個不空的ET表中的邊與AET表合并。
  3. 由AET表中取出交點對進行填充。填充之后刪除 y = y m a x y=y_{max} y=ymax?的邊。
  4. y i + 1 = y i + 1 y_{i+1}=y_i+1 yi+1?=yi?+1,根據 x i + 1 = x i + 1 / k x_{i+1}=x_i+1/k xi+1?=xi?+1/k計算并修改AET表,同時合并ET表中 y = y i + 1 y=y_i+1 y=yi?+1桶中的邊,按次序插入到AET表中,形成新的AET表。
  5. AET表不為空則轉到3,否則end。

邊緣填充算法

基本思想:按任意順序,處理多邊形的每條邊。

處理時,先求出該邊與掃描線的交點,再對掃描線上交點右方的所有像素取反。

算法簡單,但對于復雜圖形,每一個像素可能被訪問多次。

在這里插入圖片描述

柵欄填充算法

柵欄指的是一條過多邊形頂點且與掃描線垂直的直線。它把多邊形分為兩半。

基本思想:按任意順序處理多邊形的每一條邊,但處理每條邊與掃描線的交點時,將交點與柵欄之間的像素取反。
這種算法盡管減少了被重復訪問像素的數目,但仍有一些像素被重復訪問。

在這里插入圖片描述

邊界標志算法

基本思想:先用特殊的顏色在幀緩存中將多邊形的邊界勾畫出來,然后將著色的像素點依 x 坐標遞增的順序配對,再把每一對像素構成的區間置為填充色。
分為兩個步驟:打標記-多邊形掃描轉化(利用直線的掃描轉換實現),填充。

當用軟件實現本算法時,速度與改進的有效邊表算法相當,但本算法用硬件實現后速度會有很大提高

區域填充

基本概念:從區域內的某一個像素點(種子點)開始,由內向外將填充色擴展到整個區域內的過程
區域:已經表示成點陣形式的填充圖形,它是相互連通的一組像素的集合。

在這里插入圖片描述

邊界表示法:把位于給定區域的邊界上的像素一一列舉出來的方法。
邊界表示法中,由于邊界由特殊顏色指定,填充算法可以逐個像素地向外處理,直到遇到邊界顏色為止,這種方法稱為邊界填充算法。

內點表示法:枚舉出給定區域內所有像素的表示方法。

以內點表示法為基礎的區域填充算法稱為泛填充算法。

4連通區域、8連通區域:

在這里插入圖片描述

連通性:4連通可看作8連通區域,但對邊界有要求。

在這里插入圖片描述

邊界填充算法

算法的輸入:種子點坐標(x,y),填充色以及邊界顏色。

利用堆棧實現簡單的種子填充算法。

  • 算法從種子點開始檢測相鄰位置是否是邊界顏色。
  • 若不是就用填充色著色。
  • 檢測該像素點的相鄰位置。
  • 直到檢測完區域邊界顏色范圍內的所有像素為止。

特點:

  • 可以用于填充帶有內孔的平面區域。
  • 把太多的像素壓入堆棧,降低了效率,同時需要較大的存儲空間。
  • 遞歸執行,算法簡單,但效率不高,區域內每一像素都引起一次遞歸,進/出棧費時費內存。
  • 通過沿掃描線填充水平像素段,來代替處理4-鄰接點和8-鄰接點。

掃描線種子算法

掃描線通過在任意不間斷掃描線區間中只取一個種子像素的方法使堆棧的尺寸極小化。
不間斷區間是指在一條掃描線上的一組相鄰像素。

在這里插入圖片描述

基本過程:當給定種子點時,首先填充種子點所在的掃描線上的位于給定區域的一個區段,然后確定與這一區段相通的上下兩條掃描線上位于給定區域內的區段,并依次保存下來,重復以上過程。

算法步驟:在任意一個掃描線與多邊形的相交區間中, 只取一個種子像素, 并將種子像素入棧, 當棧非空時作如下四步操作:

  1. 棧頂像素出棧
  2. 沿掃描線對出棧像素的左右像素進行填充, 直至遇到邊界像素為止, 也就是對包含出棧像素的整個區間進行填充
  3. 上述區間內最左最右的像素分別記為xl和xr
  4. 在區間[xl, xr]中檢查與當前掃描線相鄰的上下兩條掃描線的有關像素是否全為邊界像素或已填充的像素, 若存在非邊界、 非填充的像素, 則把每一區間的最右像素入棧。

字符處理

ASCII碼:“美國信息交換用標準代碼集”(American Standard Code for Information Interchange)

國際碼:“中華人民共和國國家標準信息交換編碼,簡稱為國際碼,代號GB2312-80

字庫:字庫中儲存了每個字符的圖形信息

點陣字符

在點陣表示中,每個字符由一個點陣位圖來表示,顯示時,形成字符的像素圖案。

在這里插入圖片描述

特點: 定義和顯示直接、簡單、存儲需要耗費大量空間。

改進:從一組點陣字符生成不同尺寸和不同字體的其他字符、采用壓縮技術。

矢量字符

矢量字符采用直線和曲線段來描述字符形狀,矢量字符庫中記錄的是筆劃信息;顯示時:解釋字符的每個筆劃信息。

在這里插入圖片描述

輪廓字型法采用直線或二、三次曲線的集合來描述一個字符的輪廓線,輪廓線構成了一個或若干個封閉區域,顯示時只要填充這些區域就可產生相應的字符

  • 顯示時可以“無極放縮”
  • 占用空間少,美觀,變換方便

屬性處理

圖素或圖段的外觀由其屬性決定。

圖形軟件中實現屬性選擇的方法是提供一張系統當前屬性值表,通過調用標準函數提供屬性值表的設置和修改。進行掃描轉換時,系統使用屬性值表中的當前屬性值進行顯示和輸出。

線寬

線刷子:垂直刷子、水平刷子

在這里插入圖片描述

線刷子特點:

  • 實現簡單、效率高
  • 斜線與水平(或垂直)線不一樣粗
  • 當線寬為偶數個像素時,線的中心將偏移半個像素
  • 利用線刷子生成線的始末端總是水平或垂直的,看起來不太自然

解決方法:添加線帽

方帽:調整端點位置,使粗線的顯示具有垂直于線段路徑的正方形端點。

凸方帽:簡單將線向兩頭延伸一半線寬并添加方帽。

圓帽:通過對每個方帽添加一個填充的半圓得到。

在這里插入圖片描述

當比較接近水平的線與比較接近垂直的線匯合時,匯合處外角將有缺口。

在這里插入圖片描述

解決方法:斜角連接、圓角連接、斜切連接。

在這里插入圖片描述

方刷子:

方刷子繪制的線條(斜線)比用線刷子所繪制的線條要粗一些,斜線與水平(或垂直)線不一樣粗。線條自然地帶有一個“方線帽”。

利用像素模板進行線寬處理:

在這里插入圖片描述

用等距線方法:
線寬均勻、端口處與邊垂直、生成的圖形質量高。

在這里插入圖片描述

線型

用位屏蔽器實現

位屏蔽器中每一位對應的是一個像素,而不是單位長度,不能滿足要求
線型中的筆劃長度與直線長度有關
斜線筆劃長度比水平或垂直線筆劃長
對工程圖,這種變化是不允許的,不符合國標規定

用像素段方法實現:針對不同的線型,畫線程序沿路徑輸出一些連續像素段,在每兩個實心段之間有一段中間空白段,他們的長度(像素數目)可用像素模板(pixel mask)指定
如何保證任何方向的劃線長度近似相等呢?

  • 可根據線的斜率來調整實心段和中間空白段的像素數目。

在這里插入圖片描述

曲線的線性和線寬

采用像素模板的方法對圓的線型處理:

在這里插入圖片描述

  • 從一個八分象限轉入下一個八分象限時要交換像素的位置,以保持劃線長度近似相等。
  • 在沿圓周移動時調整畫每根劃線的像素數目以保證劃線長度近似相等。
  • 改進:采用沿等角弧畫像素代替用等長區間的像素模板來生成等長劃線。

曲線的線寬

線刷子:經過曲線斜率為1和-1處,必須切換刷子
(曲線接近水平與垂直的地方,線條更粗)

方刷子:接近水平垂直的地方,線條更細
(要顯示一致的曲線寬度可通過旋轉刷子方向以使其在沿曲線移動時與斜率方向一致)

圓弧刷子:采用填充方法

區域填充屬性

區域填充屬性選擇包括顏色、圖案和透明度。

確定區域與模板之間的位置關系(對齊方式)

在這里插入圖片描述

反走樣

用離散量表示連續量引起的失真,就叫做走樣。

產生原因:數學意義上的圖形是由無限多個連續的、面積為零的點構成;
光柵顯示器上,用有限多個離散的,具有一定面積的像素來近似地表示他們

走樣現象:

  1. 光柵圖形產生的階梯形
  2. 圖形中包含相對微小的物體時

在這里插入圖片描述

用于減少或消除這種效果的技術,稱為反走樣

簡單的方法:過取樣(后濾波)、區域取樣(前濾波)

分辨率提高一倍,階梯程度減小一倍

在這里插入圖片描述

過取樣

在高于顯示分辨率的較高分辨率下用點取樣方法計算,然后對幾個像素的屬性進行平均得到較低分辨率下的像素屬性。

簡單過取樣:在x,y方向把分辨率都提高一倍,使每個像素對應4個子像素,然后掃描轉換求得各子像素的顏色亮度,再對4個像素的顏色亮度進行平均,得到較低分辨率下的像素顏色亮度。。

在這里插入圖片描述

在這里插入圖片描述

重疊過取樣

為了得到更好的效果,在對一個像素點進行著色處理時,不僅僅只對其本身的子像素進行采樣,同時對其周圍的多個像素的子像素進行采樣,來計算該點的顏色屬性

在這里插入圖片描述

基于加權模板的過取樣

前面在確定像素的亮度時,僅僅是對所有子像素的亮度進行簡單的平均。更常見的做法是給接近像素中心的子像素賦予較大的權值,即對所有子像素的亮度進行加權平均。

在這里插入圖片描述

簡單的區域取樣

在整個像素區域內進行采樣,這種技術稱為區域取樣。

由于像素的亮度是作為一個整體被確定的,不需要劃分子像素,故也被稱為前置濾波。

如何計算直線段與像素相交區域的面積?

在這里插入圖片描述

  1. 將屏幕像素分割成n個更小的子像素
  2. 計算中心落在直線段內的子像素的個數m
  3. m/n為線段與像素相交區域面積的近似值。

在過取樣中,我們對所有子像素的亮度進行簡單平均或加權平均來確定像素的亮度。

在區域取樣中,我們使用覆蓋像素的連續的加權函數(Weighting Function)或濾波函數(Filtering Function)來確定像素的亮度。

將加權函數在整個二維顯示圖形上積分,得到具有一定體積的濾波器(Filter),該濾波器的體積為1
將加權函數在顯示圖形上進行積分,得到濾波器的一個子體,該子體的體積介于0到1之間,用它來表示像素的亮度。

特點:

接近理想直線的像素將被分配更多的灰度值。
相鄰兩個像素的濾波器相交,有利于縮小直線條上相鄰像素的灰度差。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/82108.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/82108.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/82108.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

怎樣避免住宅IP被平臺識別

要有效避免住宅IP被平臺識別&#xff0c;需從IP質量選擇、環境參數偽裝、行為模式模擬、技術細節處理等多維度構建防御體系。以下是基于行業實踐的綜合性解決方案&#xff1a; 一、確保住宅IP的高純凈度 選擇真實家庭網絡IP 驗證IP是否歸屬真實家庭寬帶&#xff08;非機房IP偽裝…

WPF 觸發器 Trigger

觸發器 Trigger 觸發器&#xff08;Trigger&#xff09;是 WPF 中的一種機制&#xff1a; 當某個條件滿足時&#xff0c;自動改變控件的某些屬性&#xff0c;比如顏色、大小、透明度等。 換句話說&#xff0c;就是"如果……那么就……" 的一種規則。 常見觸發器類…

NLP核心技術解析:大模型與分詞工具的協同工作原理

文章目錄 一、核心關系概述二、分詞工具的核心作用三、未登錄詞&#xff08;OOV&#xff09;問題3.1 問題本質分析3.2 解決方案3.2.1 預對齊詞匯表&#xff08;最優解&#xff09;3.2.2 子詞回退策略3.2.3 詞匯表擴展&#xff08;適合專業領域&#xff09; 3.3 技術選型建議3.4…

vscode預覽模式(點擊文件時默認覆蓋當前標簽,標簽名稱顯示為斜體,可通過雙擊該標簽取消)覆蓋標簽、新窗打開

文章目錄 VS Code 預覽模式如何取消預覽模式&#xff08;即“固定”標簽頁&#xff09;&#xff1f;預覽模式有什么用&#xff1f; VS Code 預覽模式 在 VS Code 中&#xff0c;當你單擊文件瀏覽器&#xff08;例如&#xff0c;資源管理器側邊欄&#xff09;中的某個文件時&am…

MIT XV6 - 1.1 Lab: Xv6 and Unix utilities - user/_sleep 是什么?做什么?

接上文 MIT XV6 - 1.1 Lab: Xv6 and Unix utilities - sleep 是怎樣練成的&#xff1f; user/_sleep 是什么&#xff1f; book-riscv-rev3.pdf 3.8節有對Xv6 binary文件的格式描述 Xv6 binaries are formatted in the widely-used ELF format, defined in (kernel/elf.h). An …

【AI科技】AMD ROCm 6.4 新功能:突破性推理、即插即用容器和模塊化部署,可在 AMD Instinct GPU 上實現可擴展 AI

AMD ROCm 6.4 新功能&#xff1a;突破性推理、即插即用容器和模塊化部署&#xff0c;可在 AMD Instinct GPU 上實現可擴展 AI 現代 AI 工作負載的規模和復雜性不斷增長&#xff0c;而人們對性能和部署便捷性的期望也日益提升。對于在 AMD Instinct? GPU 上構建 AI 和 HPC 未來…

【含文檔+PPT+源碼】基于微信小程序連鎖藥店商城

項目介紹 本課程演示的是一款基于微信小程序連鎖藥店商城&#xff0c;主要針對計算機相關專業的正在做畢設的學生與需要項目實戰練習的 Java 學習者。 1.包含&#xff1a;項目源碼、項目文檔、數據庫腳本、軟件工具等所有資料 2.帶你從零開始部署運行本套系統 3.該項目附帶的…

node.js模塊化步驟(各標準區別)CommonJS規范、AMD規范、UMD規范、ES Modules (ESM)

前后端建議統一使用ESM 文章目錄 Node.js模塊化發展歷程與標準對比一、模塊化的意義1.1 解決的核心問題1.2 沒有模塊化的問題 二、CommonJS規范2.1 核心特征2.2 實現示例 三、AMD (Asynchronous Module Definition)3.1 特點3.2 代碼示例 四、UMD (Universal Module Definition)…

人工智能與智能合約:如何用AI優化區塊鏈技術中的合約執行?

引言&#xff1a;科技融合的新風口 區塊鏈和人工智能&#xff0c;是當前最受矚目的兩大前沿技術。一個以去中心化、可溯源的機制重構信任體系&#xff0c;另一個以智能學習與決策能力重塑數據的價值。當這兩項技術相遇&#xff0c;會碰撞出什么樣的火花&#xff1f; 智能合約作…

RabbitMQ-api開發

前言 MQ就是接收并轉發消息 核心概念 admin是用戶 每個虛擬機上都有多個交換機 快速入門 引入依賴 <dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.22.0</version></dependen…

PostgreSQL Patroni集群組件作用介紹:Patroni、etcd、HAProxy、Keepalived、Watchdog

1. Watchdog 簡介 1.1 核心作用 ? 主節點故障檢測 Watchdog 會定時檢測數據庫主節點&#xff08;或 Pgpool 主節點&#xff09;的運行狀態。 一旦主節點宕機&#xff0c;它會發起故障切換請求。 ? 協調主備切換 多個 Pgpool 節點時&#xff0c;Watchdog 保證只有一個 Pg…

【多種不同提交方式】通過springboot實現與前端網頁數據交互(非常簡潔快速)

【多種不同提交方式】通過springboot實現與前端網頁數據交互 提示&#xff1a;幫幫志會陸續更新非常多的IT技術知識&#xff0c;希望分享的內容對您有用。本章分享的是springboot的使用。前后每一小節的內容是存在的有&#xff1a;學習and理解的關聯性。【幫幫志系列文章】&am…

使用 AI 如何高效解析視頻內容?生成思維導圖或分時段概括總結

一、前言 AI 發展的如此迅速&#xff0c;有人想通過 AI 提效對視頻的解析&#xff0c;怎么做呢&#xff1f; 豆包里面有 AI 視頻總結的功能&#xff0c;可以解析bilibili網站上部分視頻&#xff0c;如下圖所示&#xff1a; 但有的視頻解析時提示&#xff1a; 所以呢&#x…

鞅與停時 - 一種特別的概率論問題

討論一個有趣的概率問題&#xff1a; [P3334 ZJOI2013] 拋硬幣 - 洛谷 實際上是一個猴子打字問題&#xff0c;考慮一直無規律隨即打字的猴子&#xff0c;鍵盤上只有A-Z一共26個字母&#xff0c;對于一個特定的字符串 S S S &#xff1a; ABCABCAB &#xff0c;能否在有限的打…

arcgis和ENVI中如何將數據輸出為tif

一、arcgis中轉換為tif 右鍵圖層&#xff1a; Data -> Export Data, 按照圖示進行選擇&#xff0c;選擇tiff格式導出即可&#xff0c;還可以選擇其他類型的格式&#xff0c;比如envi。 二、 ENVI中轉換為tif File -> Save As -> Save As (ENVI, NITF, TIFF, DTED) …

如何用命令行判斷一個exe是不是c#wpf開發的

在powershell下執行 $assembly [Reflection.Assembly]::ReflectionOnlyLoadFrom("你的exe全路徑") $references $assembly.GetReferencedAssemblies() echo $assembly $references | Where-Object { $_.Name -match "PresentationFramework|PresentationCore…

2025.05.07-華為機考第三題300分

?? 點擊直達筆試專欄 ??《大廠筆試突圍》 ?? 春秋招筆試突圍在線OJ ?? 筆試突圍OJ 03. 城市緊急救援隊伍協同規劃 問題描述 智慧城市建設中,盧小姐負責設計一套緊急救援隊伍協同系統。城市被規劃為一個 n n n \times n

深入理解Redis SDS:高性能字符串的終極設計指南

&#x1f4cd; 文章提示 10分鐘掌握Redis核心字符串設計 | 從底層結構到源碼實現&#xff0c;揭秘SDS如何解決C字符串七大缺陷&#xff0c;通過20手繪圖示與可運行的C代碼案例&#xff0c;助你徹底理解二進制安全、自動擴容等核心機制&#xff0c;文末附實戰優化技巧&#xff…

jupyter notebook漢化教程

本章教程記錄&#xff0c;jupyter notebook漢化步驟&#xff0c;如果對漢化有需求的小伙伴可以看看。 一、安裝jupyter 如果你是安裝的anaconda的那么默認是包含了Jupyter notebook的&#xff0c;如果是miniconda或者基礎python&#xff0c;默認是不包含的jupyter組件的&#x…

模擬設計中如何減小失配

Xx 芯片測試結果顯示&#xff0c;offset 指標偏高&#xff0c;不符合指標要求。所以查看了資料&#xff0c;溫習了減小的失配的方法。 注意點一&#xff1a; 將所有offet折算到輸入端&#xff0c;得到以下公式&#xff1a; 可以看到a&#xff09;閾值電壓失配直接折算成輸…