一级工程实践—— DDA 直线算法

博客分类: 一级工程实践 阅读次数: 102 次

一级工程实践—— DDA 直线算法

我们知道,计算机屏幕是由一个个像素整齐排列而成,想要在屏幕上绘制一条直线,我们只能通过点亮屏幕中 理想直线 附近的像素点,来尽可能拟合这条直线。DDA 直线算法 可以帮我们计算出到底需要点亮哪些像素点。

DDA 算法介绍

DDA ( Digital Differential Analyzer ), 基于直线的微分方程来生成直线,典型性的光栅显示器生成算法。

假设一条直线的两端点分别为:A(x0,y0)B(x1,y1)image

则直线的斜率和方程为:
对于直线上(A,B之间)的任意一点 X (x0 + Δx, y0 + Δy) 来说, 在计算机屏幕绘制直线时,由于是点亮对应位置的像素点,所以 ΔxΔy 都必须为整数,即若计算出的值为小数时,需要四舍五入(或者向上/向下取整)。

所以这两种情况需要分别考虑:

  1. 当斜率小于等于 1 的时候,可通过计算 x方向上的增量 Δx1 个像素)引起 y 的改变来生成直线( x 每次增加 1 ,y 增加 1 或者 不增加)。 image

  2. 而当斜率大于 1 的时候,可通过计算 y 方向上的增量 Δy1 个像素)引起 x 的改变来生成直线(让 y 每次递增 1x 每次增加 1 或者 不增加 )。 image

关键代码

void lineDDA(int x0, int y0, int xEnd, int yEnd)
{
    int steps,k;
    int dx = xEnd-x0, dy = yEnd-y0;
    float xIncrement,yIncrement, x=x0,y=y0;

    //判断斜率是否大于 1,
    //steps 为增量计算的次数,也是绘制的像素点数
    if (fabs(dx)>fabs(dy))
            steps = fabs(dx);        
    else
            steps = fabs(dy);        

    //计算 x 和 y 方向上的增量
    xIncrement = float(dx)/float(steps);
    yIncrement = float(dy)/float(steps);

    //将坐标四舍五入为整数,然后点亮对应位置的像素点
    setPixel(round(x),round(y));
    for (k=0;k<steps;k++)
    {
            x = x+ xIncrement;
            y = y+ yIncrement;
            setPixel(round(x),round(y));
    }
}

运行结果示例

image