直線掃描轉換-DDA算法
直線段的掃描轉換算法
已知兩個點,求直線。
為了在光柵顯示器上用這些離散的像素點逼近這條直線,需要知道這些像素點的x,y坐標。
求出過P0,P1的直線段方程:
y=kx+b
k=(y1-y0)/(x1-x0)
假設x已知,即從x的起點x0開始,沿x方向前進一個像素(步長= 1),可以計算出相應的y值。
因為像素的坐標是整數,所以y值還要進行取整處理。
如何把數學上的一個點掃描轉換一個屏幕像素點?
p(1.7,0.8) ->(1,0)
p(1.7,0.8) +0.5->(2.2,1.3)
p(2.2,1.3) ->(2,1)
直線是最基本的圖形,一個動畫或真實感圖形往往需要調用成千上萬次畫線程序,因此直線算法的好壞與效率將直接影響圖形的質量和顯示速度。
為了提高效率,把計算量減下來,關鍵問題就是如何把乘法取消.
1、數值微分法(DDA)
2、中點畫線法
3、Bresenham算法
數值微分DDA(Digital Differential Analyzer)法
引進圖形學中一個很重要的思想---增量思想
yi=kxi+b
yi+1=kxi+1+b
=k(xi+1)+b
=kxi+k+b
=kxi+b+k
=yi+k
yi+1=yi+k
這個式子的含義是:當前步的y值等於前一步的y值加上斜率k
這樣就把原來一個乘法和加法變成了一個加法
用DDA掃描轉換連接兩點P0(0,0)和P1(5,3)的直線段。
k=(3-0)/(5-0)=0.6<1
yi+1=yi+k
x | y | int(y+0.5) |
0 | 0 | 0 |
1 | 0+0.6 | 1 |
2 | 0.6+0.6 | 1 |
3 | 1.2+0.6 | 2 |
4 | 1.8+0.6 | 2 |
5 | 2.4+0.6 | 3 |
問題:DDA畫直線算法:x每遞增1,y遞增斜率k。是否適合任意斜率的直線?
答案:不適合
當|k|>1時,如果還適用這種方法會導致點太少。
如直線點從(0,0)到(2,100),也只用3個點來表示,這樣明顯不合適。
因此當|k|>1時,交換x和y的位置。也就是以單位y間隔(δy=1)取樣,順序計算每個x值。
xi+1=xi+1/k
如從點0.0到點2,5
1/k=2/5=0.4
y | x | int(x+0.5) |
0 | 0 | 0 |
1 | 0+0.4 | 0 |
2 | 0.4+0.4 | 1 |
3 | 0.8+0.4 | 1 |
4 | 1.2+0.4 | 2 |
5 | 1.6+0.4 | 2 |