2012-12-06 58 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