考虑Rosetta Code的这个片段(用C语言编写):
void line(int x0, int y0, int x1, int y1) {
int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
int err = (dx>dy ? dx : -dy)/2, e2;
for(;;){
setPixel(x0,y0);
if (x0==x1 && y0==y1) break;
e2 = err;
if (e2 >-dx) { err -= dy; x0 += sx; }
if (e2 < dy) { err += dx; y0 += sy; }
}
}
我理解当X是驱动轴时Bresenham算法如何工作。在这种情况下,我们只是跟踪y误差,当我们增加x时,我们按比例增加y误差。如果超过某个阈值,我们也会增加y并相应地更新错误。使用一些简单的代数变化,整体可以用整数算法
完成但我无法对这个特定代码做出正面或反面。 一个变量如何同时跟踪两个错误?
答案 0 :(得分:0)
我不确定这是否是澄清问题的正确方法。让我们从这里开始。
该代码可以通过先确定 sx 和 sy 来解决不同方向的问题。它带来的另一个方便点是它可以绘制四种斜率(k) image1-1: different slope in coordinate system
像1-1所示,其他6条蓝线可以投影在k> 1和0 <= k <= 1粗体蓝线上。因此在这种情况下,我们只需要处理k> 1和0 <= k <= 1情况。
现在,让我们看一下有关不同斜率(k)值的公式。 image1-2: formula about different slope(k) value
当0 <= k <= 1 dx> dy时,我们选择err = dx / 2
e2 < dy
e2-dy < 0
(e2 - dy)/dx
= e2/dx - dy/dx (∵e2 = dx/2
= (dx/2)/dx - dy/dx
= 1/2 - k
[follow the image1-2 can know that it is exactly the initial value of error term: 0.5 - k]
在这种情况下,e2> -dx呢? 您可以绘制坐标系以模拟过程。 例如:(0,0)->(6,2)。 开头的err = 3。点(3,0)(x坐标中e2的位置)到点(-3,0)(x坐标中-dx的位置)之间的距离大于点(0,3)( y坐标中e2的位置)到(0,2)(y坐标中dy的位置)
这可能意味着,虽然 err-= dy 每次都会使err减小,但是用一种不精确的方式来表示:e2到达y坐标(e2 因此,每次在for循环中,您都将进入第一个if情况,而当e2 当k> 1为dy> dx时,我们选择err = -dy / 2 其余部分类似于前一个0 <= k <= 1的情况,不同之处在于我们每次都进入第二种if-case,并决定是否要移至第一种if-case以移动x。// inside if(e2 > -dx)
err -= dy;
err = err - dy;
err/dx = err/dx - dy/dx;
err/dx = err/dx - k;
//it is exactly: di+1 = di - k
//inside if(e2 < dy)
err += dx;
err/dx = err/dx + dx/dx;
//it is exactly: di+1 = di + 1
e2 > -dx
e2+dx > 0
(e2 + dx)/dx
= e2/dx + dx/dx (∵e2 = -dy/2
= (-dy/2)/dx - dx/dx
= -k/2 + 1
[follow the image1-2 can know that it is exactly the initial value of error term: 1 - 0.5k]