计算机辅助设计与图形学——Bresenham直线算法的实现

Bresenham直线算法原理可以很容易的找到,在此不做介绍。在算法中要注意对直线进行分类,包括直线指向第几象限以及斜率与正负1的大小比较。

判断直线指向第几象限:

  1. 直线指向第一象限:X方向的增量为正,Y方向的增量为正。
  2. 直线指向第二象限:X方向的增量为负,Y方向的增量为正。
  3. 直线指向第三象限:X方向的增量为负,Y方向的增量为负。
  4. 直线指向第四象限:X方向的增量为正,Y方向的增量为负。
斜率与正负1的大小:
若X方向增量的绝对值>Y方向增量的绝对值,则Bresenham算法每次迭代需要以x作为自变量,来判断y是否变化;
若X方向增量的绝对值

以下是用C++语言在Qt中做的Bresenham算法生成直线的主要代码,在此还需要注意的是不同的环境下的坐标系统可能不同。Qt的坐标系如图所示:

    QPainter painter(this);
    painter.drawPixmap(0, 0, pix);

    QPen pen;
    pen.setColor(Qt::black); //设置画笔的颜色
    painter.setPen(pen); //设置画笔

    //Bresenham画直线算法
    if(ButtonLineBool && flagLine)
    {
        QPainter pp(&pix);
        pp.setPen(pen);
        //pp.translate(firstPoint);
        qDebug() << firstPoint << secondPoint << endl;
        int x0 = firstPoint.x();
        int y0 = firstPoint.y(); //起点
        int x1 = secondPoint.x();
        int y1 = secondPoint.y(); //终点
        int deltaX = x1-x0, deltaY = y1-y0; // x、y方向上的增量
        int a = -deltaY, b = deltaX; //其直线方程为 ax+by+c=0
        qDebug() << a << b << endl;

        int x = x0, y = y0; //初始点
        if( deltaX>=0 && deltaY>=0 ) //第一象限
        {
            if( qAbs(deltaX)>=qAbs(deltaY) ) //第一象限,斜率小于1时,x增量
            {
                int d = 2*a+b; //避免浮点运算
                while( x<=x1 )
                {
                    pp.drawPoint(x,y);
                    if( d<0 )
                    {
                        d += 2*(a+b);
                        y++;
                    }
                    else
                    {
                        d += 2*a;
                    }
                    x++;
                }
            }
            else  //第一象限,斜率大于1时,y增量
            {
                int d = a+2*b;
                while( y<=y1 )
                {
                    pp.drawPoint(x,y);
                    if( d<0 )
                    {
                        d += 2*b;
                    }
                    else
                    {
                        d += 2*(a+b);
                        x++;
                    }
                    y++;
                }
            }
        }

        else
        {
            if( deltaX>0 && deltaY<0 ) // 第四象限
            {
                if( qAbs(deltaX)>=qAbs(deltaY) ) //第四象限,斜率大于-1时,x增量
                {
                    int d = 2*a-b; //避免浮点运算
                    while( x<=x1 )
                    {
                        pp.drawPoint(x,y);
                        if( d<0 )
                        {
                            d += 2*a;
                        }
                        else
                        {
                            d += 2*(a-b);
                            y--;
                        }
                        x++;
                    }
                }
                else  //第四象限,斜率小于-1时,y增量
                {
                    int d = a-2*b;
                    while( y>=y1 )
                    {
                        pp.drawPoint(x,y);
                        if( d<0 )
                        {
                            d += 2*(a-b);
                            x++;
                        }
                        else
                        {
                            d -= 2*b;
                        }
                        y--;
                    }
                }
            }
            else
            {
                if( deltaX<0 && deltaY>0 ) // 第二象限
                {
                    if( qAbs(deltaX)>=qAbs(deltaY) ) //第二象限,斜率大于-1时,x增量
                    {
                        int d = -2*a+b; //避免浮点运算
                        while( x>=x1 )
                        {
                            pp.drawPoint(x,y);
                            if( d<0 )
                            {
                                d -= 2*a;
                            }
                            else
                            {
                                d += 2*(-a+b);
                                y++;
                            }
                            x--;
                        }
                    }
                    else  //第二象限,斜率小于-1时,y增量
                    {
                        int d = -a+2*b;
                        while( y<=y1 )
                        {
                            pp.drawPoint(x,y);
                            if( d<0 )
                            {
                                d += 2*(-a+b);
                                x--;
                            }
                            else
                            {
                                d += 2*b;
                            }
                            y++;
                        }
                    }
                }

                else  // 第三象限 deltaX<=0 && deltaY<=0
                {
                    if( qAbs(deltaX)>=qAbs(deltaY) ) //第三象限,x增量
                    {
                        int d = -2*a-b; //避免浮点运算
                        while( x>=x1 )
                        {
                            pp.drawPoint(x,y);
                            if( d<0 )
                            {
                                d -= 2*(a+b);
                                y--;
                            }
                            else
                            {
                                d -= 2*a;
                            }
                            x--;
                        }
                    }
                    else  //第三象限,y增量
                    {
                        int d = -a-2*b;
                        while( y>=y1 )
                        {
                            pp.drawPoint(x,y);
                            if( d<0 )
                            {
                                d -= 2*b;
                            }
                            else
                            {
                                d -= 2*(a+b);
                                x--;
                            }
                            y--;
                        }
                    }
                }
            }
        }

    }
    else
    {;}


你可能感兴趣的:(图形学,图形学,Bresenham,直线,程序)