Bresenham算法
一、思想
- 通过各行、各列像素中心构造一组虚拟网格线,按照直线起点到终点的顺序,计算直线与各垂直网格线的交点,然后根据误差项的符号确定该列象素中与此交点最近的象素。
二、推导
- 假设每次 x x x增加 1 1 1, y y y的递增(减)量为 0 0 0或 1 1 1,它取决于实际直线与最近光栅网格点的距离,这个距离的最大误差为 0.5 0.5 0.5。
- 误差项
d
d
d的初值
d
0
=
0
d_0=0
d0=0,且
d = d + k ( 0 < k < 1 ) d=d+k\ \ \ \ \ \ (0<k<1) d=d+k (0<k<1)
一旦 d ≥ 1 d≥1 d≥1,就把它减去 1 1 1,保证 d d d的相对性,使 d d d在 0 0 0、 1 1 1之间。
- 推导结果
d i + 1 = d i + k d_{i+1}=d_i+k di+1=di+k ( d 0 = 0 , k = Δ y Δ x , i = 0 , 1 , 2 , 3 ⋯ , 0 < k < 1 ) (d_0=0,k=\frac{\Delta y}{\Delta x},i=0,1,2,3\cdots,0<k<1) (d0=0,k=ΔxΔy,i=0,1,2,3⋯,0<k<1)
当 d > 1 d>1 d>1时, d = d − 1 d=d-1 d=d−1;
{ x i + 1 = x i + 1 y i + 1 = { y i + 1 ( d > 0.5 ) y i ( d ≤ 0.5 ) \begin{cases} x_{i+1}&=x_i+1 \\ y_{i+1}&= \begin{cases} y_i+1 &(d>0.5)\\ y_i &(d\leq 0.5) \end{cases} \end{cases} ⎩⎪⎨⎪⎧xi+1yi+1=xi+1={yi+1yi(d>0.5)(d≤0.5)
三、改进
把个算法的效率提高到整数加法上。
-
改进1:令 e = d − 0.5 e = d-0.5 e=d−0.5,即 e i + 1 = e i + k e_{i+1}=e_i+k ei+1=ei+k, e 0 = − 0.5 e_0=-0.5 e0=−0.5。如果 e > 0 e>0 e>0, e = e − 1 e=e-1 e=e−1
{ x i + 1 = x i + 1 y i + 1 = { y i + 1 ( e > 0 ) y i ( e ≤ 0 ) \begin{cases} x_{i+1}=x_i+1 \\ y_{i+1}= \begin{cases} y_i+1 &(e>0)\\ y_i &(e\leq 0) \end{cases} \end{cases} ⎩⎪⎨⎪⎧xi+1=xi+1yi+1={yi+1yi(e>0)(e≤0) -
改进2:用 e ∗ 2 ∗ △ x e*2*△x e∗2∗△x来替换 e e e,即 e i + 1 = e i + 2 △ y e_{i+1} = e_i+2△y ei+1=ei+2△y, e 0 = − △ x e_0 = -△x e0=−△x。如果 e > 0 e>0 e>0, e = e − 2 △ x e=e-2△x e=e−2△x
{ x i + 1 = x i + 1 y i + 1 = { y i + 1 ( e > 0 ) y i ( e ≤ 0 ) \begin{cases} x_{i+1}=x_i+1 \\ y_{i+1}= \begin{cases} y_i+1 &(e>0)\\ y_i &(e\leq 0) \end{cases} \end{cases} ⎩⎪⎨⎪⎧xi+1=xi+1yi+1={yi+1yi(e>0)(e≤0)
四、总结
-
拓展
(1)以上讨论的是 0 ≤ k ≤ 1 0≤ k ≤ 1 0≤k≤1的情况,即 0 < △ y < △ x 0<△y<△x 0<△y<△x的情况;
(2)若是 1 < k 1<k 1<k,即 0 < △ x < △ y 0<△x<△y 0<△x<△y的情况,则需将 x x x和 y y y的位置交换;
(3)若 △ y < 0 △y<0 △y<0或 △ x < 0 △x<0 △x<0时,要将算法中的 y = y + 1 y=y+1 y=y+1换成 y = y - 1 y=y-1 y=y-1, x = x + 1 x=x+1 x=x+1换成 x = x - 1 x=x-1 x=x-1。 -
算法步骤
(1)输入直线的两端点 P 0 ( x 0 , y 0 ) P_0(x_0,y_0) P0(x0,y0)和 P 1 ( x 1 , y 1 ) P_1(x_1,y_1) P1(x1,y1);
(2)计算初始值 △ x = x 1 − x 0 △x=x_1-x_0 △x=x1−x0、 △ y = y 1 − y 0 △y=y_1-y_0 △y=y1−y0、 e = − △ x e=-△x e=−△x、 k = △ y △ x k=\frac{△y}{△x} k=△x△y;
(3)通过 k k k值,判断 k k k的情况;(此处默认 k k k为 0 ≤ k ≤ 1 0\leq k\leq 1 0≤k≤1)
(4)绘制点 ( x , y ) (x,y) (x,y);
(5) e e e更新为 e + 2 △ y e+2△y e+2△y,判断 e e e的符号。若 e > 0 e>0 e>0,则 ( x , y ) (x,y) (x,y)更新为 ( x + 1 , y + 1 ) ( x+1,y+1) (x+1,y+1),同时将 e e e更新为 e − 2 △ x e-2△x e−2△x,否则 ( x , y ) ( x,y) (x,y)更新为 ( x + 1 , y ) (x+1,y) (x+1,y);
(6)当直线没有画完时,重复步骤5和6。否则结束。