直線生成算法


所謂圖元的生成,是指完成圖元的參數表示形式(由圖形軟件包的使用者指定)到點陣表示形式(光柵顯示系統刷新時所需的表示形式)的轉換。通常也稱掃描轉換圖元。

直線的掃描轉換:確定最佳逼近於該直線的一組像素,並且按掃描線順序對這些像素進行寫操作。

三個常用算法:1、數值微分法DDA;2、中點畫線法;3、Bresenham算法。

生成目標,求與直線段充分接近的像素集

生成前提條件:1、像素網格均勻,坐標為整數值;2、直線段的寬度為1;3、直線段的斜率k的取值范圍為[-1,1]。

1、數值微分法

1.1 基本思想

已知過端點P0 (x0, y0), P1(x1, y1)的直線段L: y=kx+b 直線斜率為

,x從左端點x0開始,向右端點x1以步長=1(個象素),計算相應的y坐標y=kx+b;取象素點(x, y(x))作為當前點的坐標。

計算yi+1 = kxi+1+b                                   

                   = k1xi+b+kDx

                   = yi+kDx                            當Dx =1; yi+1 = yi+k 。

1.2 分析

  • x每遞增1,y遞增k(即直線斜率);
  • 注意上述分析的算法僅適用於|k| ≤1的情形。在這種情況下,x每增加1,y最多增加1。
  • 當 |k| >1時,必須把xy位置互換
  • 按照直線從(x0,y0)到(x1,y1)的方向不同,分為8個象限。對於方向在第1a象限內的直線而言, Dx=1, Dy=k。對於方向在第1b象限內的直線而言,取值Dy=1, Dx=1/k。

對應關系如下圖所示:

2、中點畫線法

2.1 基本思想

當前像素點為p(xp, yp) ,下一個象素點為P1或P2。設M=(xp+1, yp+0.5),為p1與p2的中點,Q為理想直線與x=xp+1垂線的交點。將Q與M的y坐標進行比較。

如下圖所示:

當M在Q的下方,則P2應為下一個象素點;

當M在Q的上方,應取P1為下一點。

2.2 分析

構造判別式:d=F(M)=F(xp+1,yp+0.5) = a(xp+1)+b(yp+0.5)+c

           其中a=y0-y1, b=x1-x0, c=x0y1-x1y0

當d<0,M在L(Q點)下方,取右上上方PU為下一個像素;

當d>0,M在L(Q點)上方,取右方PD為下一個像素;

當d=0,選P1或P2均可,約定取PD為下一個像素;

d是xp, yp的線性函數,因此可采用增量計算,提高運算效率。初值d0=F(x0+1, y0+0.5)=a+0.5b。

(1) 若當前象素處於d>=0情況,則取正右方像素PD(xp+1, yp), 要判下一個像素位置,應計算:di+1=F(xp+2, yp+0.5)=a(xp+2)+b(yp+0.5)=d+a; 增量為a。

(2) 若d<0時,則取右上方像素PU(xp+1, yp+1)。要判斷再下一像素,則要計算:di+1= F(xp+2, yp+1.5)=a(xp+2)+b(yp+1.5)+c=d+a+b ;增量為a+b。

畫線從(x0, y0)開始,d的初值

                    d0=F(x0+1, y0+0.5)=F(x0, y0)+a+0.5b =a+0.5b。

可以用2d代替d來擺脫小數,提高效率。

 2.3 實例演示

用中點畫線法畫出P0(0,0) ,P1(5,2)的直線。

首先構造出判別式:d = a(xp+1)+b(yp+0.5)+c 。其中a = y0 - y1 = -2,b = x1 - x0 = 5,c = x0y1 - x1y0 = 0。

則初值d0 = a + 0.5b = 0.5。取點P'(1,0)為下一個像素的位置。按照規則(1)、(2)計算,可以得到下列結果表:

i xi yi d
1 0 0 0.5
2 1 0 -1.5
3 2 1 1.5
4 3 1 -0.5
5 4 2 2.5

用坐標表示,下圖:

3、Bresenham算法

3.1 基本思想

過各行各列象素中心構造一組虛擬網格線。按直線從起點到終點的順序計算直線與各垂直網格線的交點,然后根據誤差項的符號確定該列象素中與此交點最近的象素。

3.2 分析

設直線方程為:    ,其中k=dy/dx。 因為直線的起始點在象素中心,所以誤差項d的初值d0=0。

x下標每增加1,d的值相應遞增直線的斜率值k,即ddk。一旦d≥1,就把它減去1,這樣保證d在0、1之間。

d≥0.5時,最接近於當前象素的右上方象素(xi+1,yi+1)

d<0.5時,更接近於右方象素(xi+1,yi)。

為方便計算,令ed-0.5,e的初值為-0.5,增量為k

e≥0時,取當前象素(xiyi)的右上方象素(xi+1,yi+1);

當e<0時,更接近於右方象素(xi+1,yi)。

3.3 實例演示

用Bresenham算法畫出P0(0,0) ,P1(5,2)的直線。

計算得出斜率k = dy/dx = 0.4。

結果如下表:

i x y e
1 0 0 -0.5
2 1 0 -0.1
3 2 1 0.3
4 3 1 -0.3
5 4 2 0.1
6 5 2 -0.5

坐標表示:

上述Bresenham算法在計算直線斜率與誤差項時用到小數與除法。可以改用整數以避免除法。由於算法中只用到誤差項的符號,因此可作如下替換

         這樣e’的初值是-dx,由於k=dy/dx,所以e’的增量就變為2*dy。

3.4 Bresenham算法的優點

  • 不必計算直線斜率,因此不做除法;
  • 不用浮點數,只用整數;
  • 只做整數加減法和乘2運算,而乘2運算可以用硬件移位實現。
  • Bresenham算法速度很快,並適於用硬件實現。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM