图形学(9)画线

时间:2021-09-15 16:28:40

画线算法

1. 计算机画线

真实的直线应该是连续的,但是计算机不可能显示出完全连续平滑的直线,于是计算机用一系列 离散化的像素点 来表示直线
图形学(9)画线
(《计算机图形学的概念与方法》柳朝阳)

2. 常用画线算法

2.1 DDA算法

图形学(9)画线

DDA是一种基于直线的 微分方程 来生成直线的方法

  1. 基本的直线微分: dydx=k

  2. 跟据步长(也即像素数目)即可计算出 xy 坐标:
    步长取 Stepxyi+1=yi+k
    OR
    步长取 Stepyxi+1=xi+1k

  3. 其中步长取 Stepx 还是 Stepy
    考虑两端点之间水平距离 |Δx|=|x2x1| 与竖直距离 |Δy|=|y2y1|
    绝对值大 的确定步长

  4. 从起始位置 (x1,y1) 开始, 按照步长,沿线段路径计算每一步下一个像素的位置

  5. 调整每一步的 x y ,逐一绘制余下像素。

DDA算法 比起根据 直线方程计算离散取样 的方法省去了乘法,加快了计算。
但是 取整操作浮点运算 仍然十分费时。

2.2 Bresenham算法

该算法仅使用增量整数计算

图形学(9)画线

Bresenham通过计算两像素与实际线段的偏移比值的整型参数的符号比较来确定所取像素

  1. 当斜率K大于1时,在Y方向上以单位步长移动,计算x值,
    当斜率在0到1 之间时,在X方向上以单位步长移动。

  2. 其中步长取 Stepx 还是 Stepy
    考虑两端点之间水平距离 |Δx|=|x2x1| 与竖直距离 |Δy|=|y2y1|
    绝对值大 的确定步长

  3. 设 |k|<1 ,第k步时, (xk,yk) 开始,判断下一位置取 (xk+1,yk) 还是 (xk+1,yk+1) ,假设 dlower dupper 来表示两个像素与数学上线段路径的垂直偏移

线xk+1yy=m(xk+1)+b
那么
dlower=yyk=m(xk+1)+byk

dupper=(yk+1)y=(yk+1)m(xk+1)b

要确定两像素中哪一个更接近线路经,作差

dlowerdupper=2m(xk+1)2yk+2b1
定义决策参数:

pk=Δx(dlowerdupper)=2Δyxk2Δxyk+c(c)

可以继续推导出:
pk+1=2Δyxk+12Δxyk+1+c pk+1pk=2Δy(xk+1xk)2Δx(yk+1yk)

xk+1=xk+1 ,
{pk+1p0=pk+2Δy2Δx(yk+1yk),=2ΔyΔxyk+1yk01pk

|k|<1时,Bresenham画线算法具体步骤如下:

  1. 输入线段的两个端点,存储左端点在 (x0,y0) 中;
  2. (x0,y0) 装入帧缓存,画出第一个点;
  3. 计算常量 Δx,Δy,2Δy,2Δy2Δx , 得到第一个决策参数
    p0=2ΔyΔx
  4. i=0 开始,在沿线段路径的每个 xi 处进行下列检测:
    如果 pk<0 ,下一个要绘制的点为 (xi+1,yi) , 并且 pi+1=pi+2Δy
    否则,下一个要绘制的点为 (xi+1,yi+1) , 并且 pi+1=pi+2Δy2Δx
  5. 重复步骤4, 共 Δx1 次。