如何在屏幕上绘制直线
问题定义:给到两个点p1(x1,y1),p2(x2,y2);请在屏幕像素空间绘制一条直线。
最简单的方案
根据两点坐标p1(x1,y1),p2(x2,y2),可求出如下直线方程:
y=kx+bk=(y2−y1)/(x2−x1)
根据直线方程,可以得到直线绘制算法如下:
x = x1
while(x < x2) {
y = (int)(kx + b);
drawPoint(x, y);
x++;
}
缺点:
在本算法中,有一次k * x这样的浮点数乘法运算以及一次+b这样的浮点数加法运算。
浮点数运算效率较低,可否找到一种算法,只运用整数的四则运算呢?
Brensenham直线绘制算法
本算法整体的计算过程中,只使用了整数型数据进行运算与决策,省略了浮点数运算,从而提高了绘制效率
我们先考虑最简单情况:
- x1<x2
- 二者构成的直线斜率: 0<k<1
如图红色监听所示:

该直线方程为:
y=kx+bk=(y2−y1)/(x2−x1)

假设当前直线已经通过点(xi,yi),那么当x方向前进+1时 (即xi+1=xi+1),如何确定yi+1的值?

d0=(yi+1)−(k∗(xi+1)+b)d1=(k∗(xi+1)+b)−yi
d1−d0=k∗(xi+1)+b−yi−yi−1+k∗(xi+1)+b=2k∗(xi+1)−2yi−1+2b
通过判断 d1−d0 的正负值,就能确定yi+1取哪一像素点。
由已知条件
k=(y2−y1)/(x2−x1)Δx=(x2−x1)>0
令 pi=Δx∗(d1−d0),可得:
pi=2Δy∗(xi+1)−Δx(2yi+1−2b)=2Δy∗xi+2Δy−2Δx∗yi−Δx+2Δx∗b=2Δy∗xi−2Δx∗yi+(2Δy+2Δx∗b−Δx)
此时就可以通过 pi 的正负判断选择那个像素。
其中(2Δy+2Δx∗b−Δx) 可以提前求得。

{pi>0,d1>d0,yi+1=yi+1pi<0,d1<d0,yi+1=yi
迭代模型
我们已经知道了任何一个p的表达式,那么是否可以利用迭代法来计算每个接下来的p呢?
pi=2Δy∗xi−2Δx∗yi+(2Δy+2Δx∗b−Δx)pi+1=2Δy∗(xi+1)−2Δx∗yi+1+(2Δy+2Δx∗b−Δx)pi+1−pi=2Δy−2Δx∗(yi+1−yi)
考察第一个p值,带入x1,y1=k∗x1+b
p1=2Δy∗x1−2Δx∗(ΔxΔy∗x1+b)+(2Δy+2Δx∗b−Δx)p1=2Δy−Δx
得到直线绘制算法如下:
x = x1, y = y1;
p = 2Δy - Δx;
while(x < x2) {
drawPoint(x, y);
x++;
if(p >= 0) {
y++;
p = p - 2Δx;
}
p = p + 2Δy;
}
注意:本方法只对满足前置条件的直线生效:
- x1<x2
- 二者构成的直线斜率: 0<k<1





