2012-12-06 104 views
0

Bresenham的浮點算法中存在一些讓我惱火的問題。Bresenham Lines Drawing Alogrithm

該算法如下:

void line(x0, x1, y0, y1) 
{ 
    int deltax = x1 - x0; 
    int deltay = y1 - y0; 
    float error = 0; 
    float deltaerr = Math.abs((float)deltay/(float)deltax); 
    int y = y0 

    for(int x=x0;x<=x1;x++) 
    { 
    SetPixel(x,y) 
    error = error + deltaerr 
    if (error >= 0.5) 
    { 
      y = y + 1 
      error = error - 1.0 
    } 
    } 
} 

假設我們要繪製Y = 0.6X。 因此,在x = 0的第一步中:錯誤將被設置爲0.6,我們將遇到if語句和y 將增加。錯誤將被設置爲-0.4。 -0.4如何在下一步中幫助我們?

所以我的問題是這行代碼:

error = error - 1.0 

爲什麼我們應該以1死亡的錯誤?我讀過,因爲重新調整,我們這樣做!它如何幫助我們?

+3

你有沒有看過[真正的算法](http://en.wikipedia.org/wiki/Bresenham's_line_algorithm#Algorithm)?因爲你所展示的只是部分正確 –

+0

,所以爲什麼維基百科把它放在頁面的頂部? –

回答

5

錯誤積累。當它大於半個像素時,該線被移動一個像素,然後錯誤必須再次被整個像素校正。

如果您只是簡單地將錯誤歸零,那麼您只會取消部分錯誤,因此該行會過早地再次出現,並且會是錯誤的漸變。

在您的例子爲Y = 0.6X,如果計算錯誤,但零出來,會發生以下情況:

error = 0; 
plot pixel; 
increment error. error = 0.6; 
error > 0.5, so move over and reset error to 0; 
plot pixel; 
increment error. error = 0.6; 
error > 0.5, so move over and reset error to 0; 
plot pixel; 
increment error. error = 0.6; 
error > 0.5, so move over and reset error to 0; 
... 

所以行實際上具有1的梯度;事實上,任何具有大於等於0.5的梯度的線都是相同的,這顯然不是很有用。

如果你這樣做是正確:

error = 0; 
plot pixel; 
increment error. error = 0.6; 
error > 0.5, so move over and subtract one; error = -0.4; 
plot pixel; 
increment error. error = 0.2; 
plot pixel; 
increment error. error = 0.8; 
error > 0.5, so move over and subtract one; error = -0.2; 
... 

該生產線具有正確的梯度,因爲錯誤充當定點運算的小數部分。

+0

請詳細解釋.... –

+0

感謝您的解釋,但是否有選擇1進行減法的理由?爲什麼不是0.5? –

+0

這就是上面的解釋。該誤差表示像素的小數部分。當移動超過1個像素時,您必須從錯誤中減去1。 – JasonD

0

errorideal_y-current_y

當我們進入,我們沒有接觸y增加x循環的下一次迭代。在此操作之後,error=error+deltaerr更新爲error

如果我們決定增加y,我們再次必須更新error,那就是error=error-1

+0

我注意到我們應該重新調整錯誤,我的問題是爲什麼e = e-1,爲什麼不e = 0? –

+0

是否意味着錯誤=錯誤+ deltaerr會將當前x的錯誤設置爲理想值y? –

+0

,因爲ideal_y可能不是一個整數,而current_y總是,所以即使在校正之後,錯誤也可能不爲零 – maxim1000