算法过程推导
详细推导过程
注意:推导过程一文中的代码,由于缺少了针对不同方向的情况,因此不可使用。
算法代码
void Bresenham_line(int x1, int y1, int x2, int y2)
{
// increx即Δx increy即Δy interchange记录最大位移方向(也即目标直线的斜率)
int x, y, s1, s2, increx,
increy, temp, interchange;
int e, i;
x = x1;
y = y1;
// sign函数当参数为正返回1,为负返回-1,为0返回0
// s1 s2 分别记录 x轴和y轴的迭代增量
s1 = sign(x2 - x1);
s2 = sign(y2 - y1);
// Δy=(y2-y1) Δx=(x2-x1)
increx = abs(x2 - x1);
increy = abs(y2 - y1);
// 判断斜率是否处于(0,1) k=(y2-y1)/(x2-x1) 即判断Δy是否大于Δx
if (increy > increx)
{
// 若 Δy>Δx 即 斜率>1 ,则最大位移方向为y方向,每次迭代y+1
// 由于算法是针对 最大位移方向为x方向,所以交换 xy轴信息,并记录interchange=1表示y方向
temp = increx;
increx = increy;
increy = temp;
interchange = 1;
}
else
interchange = 0;
// 推导中p0=2Δy−Δx (如果最大位移方向为y方向,由于交换了increx和increy的值,所以此处计算正确)
e = 2 * increy - increx;
// 不确定是迭代x轴还是y轴,所以使用无关的迭代计数器i,i表示要完成的迭代步数,即最大位移的值
for (i = 1; i <= increx; i++)
{
putpixel(x, y, RED);
if (e >= 0)
{
if (interchange == 1)
x = x + s1;
else
y = y + s2;
e = e - 2 * increx;
}
if (interchange == 1)
y = y + s2;
else
x = x + s1;
e = e + 2 * increy;
// 上述代码可能看起来有点复杂,下面做分析
/* 当 interchange = 0 即迭代x轴方向时,和推导中一样
当e>=0时:
y = y + s2
x = x + s1
e = e + 2 (increy-increx)
当e<0时:
x = x + s1
e = e + 2 * increy
当 interchange = 1 即迭代y轴方向时
当e>=0时:
x = x + s1
y = y + s2
e = e + 2 (increy-increx)
当e<0时:
y = y + s2
e = e + 2 * increy
分析上述代码执行,发现和推导中是一样的,要注意s1 s2代表迭代方向,如第二象限xy轴迭代方向分别为:-1 +1。
当迭代方向为y轴时,由于交换了increy和increx的值,所以计算没有问题
*/
}
}