Bresenham方法也是在两个点中进行选择的过程,但其避开了所有的乘除法操作(可用位运算代替),而且只有整型的计算。
对于直线y= kx + b,dx= x1 – x0,dy= y1 – y0。当y1> y0,x1> x0且k<= 1时,设误差e的初值为-dx / 2,每次x增加1,让e+= dy,当e的符号发生改变的时候,就是y应该加1的时候,这时再让e-=dy。本质上Bresenham法就是用整数的加减代替了斜率的计算,同样可以将增量全部乘以2来避免浮点数运算,乘以2的操作可以用移位代替。
为了让画线的程序可以高效的执行,这里用重复的代码来换取速度。当|k|<=1时,如果x0> x1,可以交换两点,保证绘制向右进行。当|k|>1时,调换x和y的位置即可套用程序。
基本代码:
void draw_line_Bresenham_4i(int32 x0, int32 y0, int32 x1, int32 y1)
{
int32 dx, dy, e;
if(abs(y1 - y0) < abs(x1 - x0))
{
if(x0 > x1)
{
swap(x0, x1);
swap(y0, y1);
}
dx = (x1 - x0) << 1;
dy = (y1 - y0) << 1;
e = - (dx >> 1);
if(y0 < y1)
{
while(x0 != x1)
{
draw_point_pen_2i(x0, y0);
++ x0;
e = e + dy;
if(e >= 0)
{
++ y0;
e -= dx;
}
}
}
else
{
while(x0 != x1)
{
draw_point_pen_2i(x0, y0);
++ x0;
e = e + dy;
if(e <= 0)
{
-- y0;
e += dx;
}
}
}
}
else
{
if(y0 > y1)
{
swap(x0, x1);
swap(y0, y1);
}
dx = (x1 - x0) << 1;
dy = (y1 - y0) << 1;
e = - (dy >> 1);
if(x0 < x1)
{
while(y0 != y1)
{
draw_point_pen_2i(x0, y0);
++ y0;
e = e + dx;
if(e >= 0)
{
++ x0;
e -= dy;
}
}
}
else
{
while(y0 != y1)
{
draw_point_pen_2i(x0, y0);
++ y0;
e = e + dx;
if(e <= 0)
{
-- x0;
e += dy;
}
}
}
}
}