1. 程式人生 > >計算機圖形學(三種畫線算法)

計算機圖形學(三種畫線算法)

直線 情況 算法 n) src 隨著 多邊形 取整 兩個

第二章:光柵圖形學算法

1光柵顯示器:光柵掃描式圖形顯示器簡稱光柵顯示器,是畫點設備,可看作是一個點陣單元發生器,並可控制每個點陣單元的亮度

2、由來:隨著光柵顯示器的出現,為了在計算機上處理、顯示圖形,需要發展一套與之相適應的算法。

3、研究內容:

1>直線段的掃描轉換算法

2>多邊形的掃描轉換與區域填充算法

3>裁剪算法

4>反走樣算法

5>消隱算法

一、直線段的掃描轉換算法

1.為了顯示一條直線,就在光柵顯示器上用離散的像素點逼近直線,所以我們就要知道這些像素點的坐標

技術分享圖片

已知P0P1,利用斜截式方程,y=kx+b,求出k=y1-y0/(x1-x0),b為截距

現在k,b已知,x,y未知,現在假設一個像素距離為y,即可求出y的值。

因為像素的坐標是整數,所以y值還要進行取整處理

2.在計算機中加法的運算更快,乘法較慢,故可以把上述方法優化來提高效率

1>數值微分法(DDA

2>中點劃線法

3>Bresenham算法

數值微分法(DDA-----增量算法(只有一個加法)

技術分享圖片技術分享圖片

這個式子的含義是:當前步的y值等於前一步的y值加上斜率k(增量)

例子:

技術分享圖片

思考:x遞增1y遞增k,是否適合任意的k

可改進的點:

1>一般情況下,k都是小數,且每一步均要對y四舍五入,唯一改進的途徑是把浮點運算變為整數加法!

2>方程還有兩點式,一般式

|k|<=1時,偽代碼如下:

voidDDALine(int x0,int y0,int x1,int y1,int color){

Int x;

Float dx,dy,y,k;

dx=x1-x0;dy=y1-y0;

K=dy/dx;y=y0;

For(x=x0,x<=x1;x++){

Drawpixel(x,int(y+0.5),color);//drawpixel(x, y, color)(x, y)像素點繪制顏色為color的點

Y=y+k;

}

}

中點畫線法

技術分享圖片

采用直線的一般式方程:Ax+By+C=0 F(x,y)=0,其中a = y0 - y1b = x1 - x0c = x0y1 - x1y0

F(x, y)=0則得出直線方程,代入 (x0, y0)(x1, y1),便可得到三個方程,可求出a,b,c的值

一條直線把平面分成了三個部分,直線上方,直線上,直線下方

技術分享圖片

x方向上+1y方向上加不加1需判斷

技術分享圖片

如何判斷QM的上方還是下方?

M點的坐標帶入方程,其中a = y0 - y1b = x1 - x0

技術分享圖片

分析計算量?

兩個乘法,四個加法,推導出d的增量公式

技術分享圖片d的初始值包含小數,因此可以用2d來代替d實現整數加法,所以d=2a+b

偽代碼如下:

Void MidPointLine(int x0,int y0,int x1,int y1,int color){

Int a,b,delta1,delta2,d,x,y;

a=y0-y1;b=x1-x0;

d=2*a+b;

Delta1 = 2*a;

Delta2 =2*(a+b);

X = x0;

Y=y0;

//在對應的x,y像素點著色

putpixel(x,y,GREEN);

while(x<x1)

{

if(d<0)

{x++;y++;d+=delta2;}

else

{x++;d+=delta1;}

//在對應的x,y像素點著色

putpixel(x,y,GREEN);

}

Bresenham算法

每步的進化:

DDA把算法效率提高到每步只做一個加法

中點算法進一步把效率提高到每步只做一個整數加法

Bresenham算法提供了一個更一般的算法,該算法不僅有好的效率,而且有更廣泛的適用範圍

技術分享圖片

技術分享圖片

技術分享圖片

如何把算法的效率也提高到整數加法?

改進一:

e=d-0.5

技術分享圖片

因為d的初值為0,所以e的初值為-0.5

計算機圖形學(三種畫線算法)