您的位置:首页 > 理论基础

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

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

判断直线指向第几象限:

直线指向第一象限:X方向的增量为正,Y方向的增量为正。
直线指向第二象限:X方向的增量为负,Y方向的增量为正。
直线指向第三象限:X方向的增量为负,Y方向的增量为负。
直线指向第四象限:X方向的增量为正,Y方向的增量为负。
斜率与正负1的大小:

若X方向增量的绝对值>Y方向增量的绝对值,则Bresenham算法每次迭代需要以x作为自变量,来判断y是否变化;
若X方向增量的绝对值<Y方向增量的绝对值,则Bresenham算法每次迭代需要以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
{;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: