用bresenham算法绘制一条直线

一、

环境准备:1.visual studio 2022 2.Qt 13.0.1

二、

核心算法思想:

首先需要起点(x1,y1),终点(x2,y2)

Y=m(xi+1)+b

D1=y-yi

D2=yi+1-y

Pi+1=pi+2dy-2(yi+1-yi)dx

P1=2dy-dx

核心在于比较d1,d2,从而根据前一个点的y坐标,去判断后一个点的y坐标。

三、

代码实现:

1.首先在visual studio创建一个Qt Widgets Application项目

如下图所示:

2.点击项目结构里的Source Files文件夹

三、再点击文件夹下的.cpp文件,注意:点击你所创建的项目名的.cpp文件,我在这里的项目文件名为ex0103,建议使用驼峰命名法,我的命名并不算规范。

四、在.cpp文件中写代码

void ex0103::bress(QImage *image ,int x1,int y1,int x2,int y2,Qrgb value)//这个函数需要传递的参数为起点坐标,终点坐标,至于剩下的两个形参是所必须设置的,在这里不必详细了解。

{

int dx,dy,x,y,p,const1,const2,inc,tmp;

dx=x2-x1;//两个点x的差值,为求斜率作准备

dy=y2-y1;//同理

if(dx*dy>=0)//可以理解为斜率是正是负,也就可以知道直线整体的方向

{

inc=1;

}

else

inc=-1;//只有一行可以不用加括号,上面的if其实也可以

if(abs(dx)>abs(dy))//这是用来判断在哪个方向上的增速快,就将哪个方向定义为主方向

{

if(dx<0)//说明终点(x2,y2)的值要比起点要小,因此我们交换终点起点的横纵坐标

{     

tmp=x1;//tmp看作一个用来过渡的中间量即可

x1=x2;交换横坐标

x2=tmp;//横坐标到此完成交换

tmp=y1;//tmp看作一个用来过渡的中间量即可

y1=y2;交换纵坐标

y2=tmp;//纵坐标到此完成交换

dx=-dx;//dx也需要更新,这里更新不需要重新计算,求相反数即可

dy=-dy;//同理

}

p=2*dy-dx;//这个公式由前面的理论推出,这是这个算法的核心,需要通过p的正负来判断y取什么值

const1=2*dy;//这是前面理论推出的公式中的一部分,可以看成一个常量

const2=2*(dy-dx)//同上

x=x1;//准备开始描点

y=y1;同上

image->setPixel(x, y, value);从起点开始描点

while(x<x2)//循环终止条件为到终点截止

{

x++;//已经确定了x为主方向,也已经知道终点比起点大,所以我们固定x的增量始终为1

if(p<0)//根据前面理论可知,p的正负决定了,y的取值

{

p+=const1;理论公式得出,此时y的值沿用上一个点的y值

}

else{

y+=inc;//此时y值应该发生改变

p+=const2//使用另一个公式

}

image->setPixel(x, y, value);//描点

}

}

//下面这部分代码与上面代码的思想十分相同,可以参照理解

    else {
        if (dy < 0)
        {
            tmp = x1;
            x1 = x2;
            x2 = tmp;
            tmp = y1;
            y1 = y2;
            y2 = tmp;
            dx = -dx;
            dy = -dy;
        }
        p = 2 * dx - dy;
        const1 = 2 * dx;
        const2 = 2 * (dx - dy);
        x = x1;
        y = y1;
        image->setPixel(x, y, value);
        while (y < y2)
        {
            y++;
            if (p < 0) {
                p += const1;

            }
            else {
                x += inc;
                p += const2;
             
            }
            image->setPixel(x, y, value);
        }
    }

}

四、得出结果

生成了一条直线

五、总结

算法仍然存在不足之处。

                  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值