Bresenham算法详解

Bresenham算法

一、思想

  • 通过各行、各列像素中心构造一组虚拟网格线,按照直线起点到终点的顺序,计算直线与各垂直网格线的交点,然后根据误差项的符号确定该列象素中与此交点最近的象素。在这里插入图片描述

二、推导

  1. 假设每次 x x x增加 1 1 1 y y y的递增(减)量为 0 0 0 1 1 1,它取决于实际直线与最近光栅网格点的距离,这个距离的最大误差为 0.5 0.5 0.5
  2. 误差项 d d d的初值 d 0 = 0 d_0=0 d00,且
    d = d + k        ( 0 < k < 1 ) d=d+k\ \ \ \ \ \ (0<k<1) ddk      (0<k<1)
    一旦 d ≥ 1 d≥1 d1,就把它减去 1 1 1,保证 d d d的相对性,使 d d d 0 0 0 1 1 1之间。
    在这里插入图片描述
  3. 推导结果
    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=d1
    { 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)(d0.5)

三、改进

把个算法的效率提高到整数加法上。

  1. 改进1:令 e = d − 0.5 e = d-0.5 e=d0.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=e1
    { 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)(e0)

  2. 改进2:用 e ∗ 2 ∗ △ x e*2*△x e2x来替换 e e e,即 e i + 1 = e i + 2 △ y e_{i+1} = e_i+2△y ei+1=ei+2y e 0 = − △ x e_0 = -△x e0=x。如果 e > 0 e>0 e>0 e = e − 2 △ x e=e-2△x e=e2x
    { 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)(e0)

四、总结

  1. 拓展
    (1)以上讨论的是 0 ≤ k ≤ 1 0≤ k ≤ 1 0k1的情况,即 0 < △ y < △ x 0<△y<△x 0yx的情况;
    (2)若是 1 < k 1<k 1<k,即 0 < △ x < △ y 0<△x<△y 0xy的情况,则需将 x x x y y y的位置交换;
    (3)若 △ y < 0 △y<0 y0 △ x < 0 △x<0 x0时,要将算法中的 y = y + 1 y=y+1 yy1换成 y = y - 1 y=y-1 yy1 x = x + 1 x=x+1 xx1换成 x = x - 1 x=x-1 xx1

  2. 算法步骤
    (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=x1x0 △ y = y 1 − y 0 △y=y_1-y_0 y=y1y0 e = − △ x e=-△x e=x k = △ y △ x k=\frac{△y}{△x} k=xy
    (3)通过 k k k值,判断 k k k的情况;(此处默认 k k k 0 ≤ k ≤ 1 0\leq k\leq 1 0k1
    (4)绘制点 ( x , y ) (x,y) (x,y);
    (5) e e e更新为 e + 2 △ y e+2△y e+2y,判断 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 e2x,否则 ( x , y ) ( x,y) (x,y)更新为 ( x + 1 , y ) (x+1,y) (x+1,y)
    (6)当直线没有画完时,重复步骤5和6。否则结束。

  • 8
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值