在上一节直线是不是陡的[202302141813] ,我们成功把一条陡的直线变成不陡的(见下图直线A'B’),但它和标准斜率标准斜率[202302141842] 其实还有些不同:

Untitled

所以我们还需要一步变换。

当点A在点B的右侧时,将两点整个地交换:

Untitled

翻译成代码是这样的:

using namespace std;
void line_bresenham(int x0, int y0, int x1, int y1, TGAImage& image, TGAColor& color)
{
    int dx = x1 - x0; // 两点之间的水平距离
    int dy = y1 - y0; // 两点之间的垂直距离
    bool is_steep = false; // 直线的斜率是否大于 45 度?

    // 判断直线的斜率是否大于 45 度,如果是则需要按 y = x 对称
    if (abs(dx) < abs(dy)){
        is_steep = true;
        swap(x0, y0);
        swap(x1, y1);
    }

		// 确保 x0 <= x1
		if(abs(x0) > abs(x1))
		{
				swap(x0, x1);
				swap(y0, y1);
		}
}

高亮代码含义:在执行绘制像素的操作之前,代码还需要确保 x0 小于等于 x1,这是因为在 x 轴上向左和向右移动可能会导致绘制的像素缺失。

通过以上两节,我们就完成了将一条直线转换成标准斜率的操作:

Untitled

由于线段的起点和终点的坐标已经发生了改变,我们需要在代码中更新dx和dy的值:


using namespace std;
void line_bresenham(int x0, int y0, int x1, int y1, TGAImage& image, TGAColor& color)
{
    int dx = x1 - x0; // 两点之间的水平距离
    int dy = y1 - y0; // 两点之间的垂直距离
    bool is_steep = false; // 直线的斜率是否大于 45 度?

    // 判断直线的斜率是否大于 45 度,如果是则需要按 y = x 对称
    if (abs(dx) < abs(dy)){
        is_steep = true;
        swap(x0, y0);
        swap(x1, y1);
    }

		// 确保 x0 <= x1
		if (x0 > x1)
		{
		    swap(x0, x1);
		    swap(y0, y1);
		}
		
		// 更新值
		dx = x1 - x0;
		dy = y1 - y0;
}