• Bresenham直线生成算法详解


    基本思想

            比较从理想直线到位于直线上方的像素的距离t和相邻的位于直线下方的像素的距离s,根据距 离误差项的符号确定与理想直线最近的像素,如下图所示:

    简言之就是判断t和s哪个点距离直线更近

    判断 s-t 的大小

            已知当前的像素的中心点坐标为(xi,yi),根据 s-t 的值来判断下一步的点所在位置。详细计算推导过程如下:

    \because 设位于s、t之间直线的坐标(x,y),得到  s=y-y_{i} , t=y_{i}+1-y

    \therefore s-t=y-y_{i}-(y_{i}+1-y)=2y-2y_{i}-1

    \because  x_{i}=x_{i+1} 时,真实的直线y值为:y=m\left ( x_{i}+1 \right )+b ,

    \therefore 2y-2y_{i}-1=2(mx_{i}+m+b)-2y_{i}-1

    \because m代表直线的斜率(slope),故m=\frac{\Delta y}{\Delta x},

    \therefore  在原式两边同时乘上\Delta x,原式 = \Delta x(s-t)=2\Delta yx_{i}+2\Delta y+2\Delta xb-2\Delta xy_{i}-\Delta x

    \because 我们的目的是判断 s-t 是大于0的还是小于0的,且由于\Delta x恒大于0,所以我们可以令

    d_{i}=\Delta x(s-t) ,此时 d_{i} s-t 正负方向一致,可以用来代替 s-t 来判断其大小。由于判断的是正负性,所以一些已知项可以当成常数C来看。

    \therefore d_{i}=2\Delta yx_{i}-2\Delta xy_{i}+C

    此时d_{i+1}=2\Delta yx_{i+1}-2\Delta xy_{i+1}+C

    联立两个式子,注意代入 x_{i+1}=x_{i}+1,然后求 d_{i+1}-d_{i} ,结果得到:

    d_{i+1}-d_{i}=2\Delta y-2\Delta x\left ( y_{i+1}-y_{i} \right )

    \because 当我们选择直线上方的点的话,那么 d_{i}>0 ,y_{i+1}-y_{i}=1,此时

    d_{i+1}=d_{i}+2(\Delta y-\Delta x) ;

    反之 d_{i+1}=d_{i}+2\Delta y

    \therefore 最终推出以下式子:

    d_{i+1}=\left\{\begin{matrix} d_{i}+2(\Delta y-\Delta x) , d_{i}\geq 0 \\\\ d_{i}+2\Delta y , d_{i}< 0 \end{matrix}\right.

    此时 d_{i+1} 就代表了 s-t 的正负性,当 d_{i}\geq 0 ,代表了 比 大,所以要取上面的一格,即y_{i+1}=y_{i}+1 ; 反之取的格子位置不变,即 y_{i+1}=y_{i} 。

    接下来看一道例题,来体会一下breseham算法的应用。

    例题

    首先先画好直线段:

    接着通过求x,y,d_{i} 三个变量的值来确定像素的坐标位置:

    第一个像素点位置就是起点,即(0,0),x_{1}=0,y_{1}=0

    初始的误差值d_{1} ,由前面的式子 d_{i}=2\Delta yx_{i}+2\Delta y+2\Delta xb-2\Delta xy_{i}-\Delta x,令 i = 1

    得:

     d_{1}=2\Delta yx_{1}+2\Delta y+2\Delta xb-2\Delta xy_{1}-\Delta x=2\Delta yx_{1}+2\Delta y+2\Delta xb-2\Delta x(\frac{\Delta y}{\Delta x})-\Delta x=2\Delta y-\Delta x

    所以得值 d_{1} = 2\Delta y-\Delta x = -1。

    综上第一个点,三个参数是x_{1}=0,y_{1}=0,d_{1}=-1

    第二个点,x一定往右一格,所以此时x_{1}=1

    因为上一格求得的误差d_{1}=-1< 0,所以此时 y_{i+1}=y_{i},即y_{2}=0

    由于d_{1}< 0,故 d_{2}=d_{i}+2\Delta y=3

    综上第二个点,三个参数是x_{2}=1,y_{2}=0,d_{2}=3

    第三个点,x一定往右一格,所以此时x_{2}=2

    因为上一格求得的误差d_{2}=3> 0,所以此时 y_{i+1}=y_{i}+1,即y_{3}=1

    由于d_{2}> 0,故 d_{3}=d_{i}+2(\Delta y-\Delta x)=-3

    综上第三个点,三个参数是x_{2}=2,y_{2}=1,d_{3}=-3

    依次类推······

    结果如图:

     得到的坐标依次为(0,0) (1,0) (2,1) (3,1) (4,2) (5,2)

    根据坐标填充像素:

     此时,breseham算法生成直线像素已完成。

    代码描述(C语言伪代码)

    1. //Bresenham
    2. void Bes_line(int x0,int y0,int x1,int y1){
    3. int dx,dy,h,x,y;
    4. dx=abs(x0-x1);
    5. dy=abs(y0-y1);
    6. h=2*dy-dx;
    7. x=x0;
    8. y=y0;
    9. glColor3f(1.0, 0.0, 0.0);
    10. glBegin(GL_POINTS);
    11. glVertex2f(x,y);
    12. while (x
    13. {
    14. if(h<0) h+=2*dy;
    15. else{
    16. h=+2*(dy-dx);
    17. y++;
    18. }
    19. glVertex2f(x,y);
    20. x++;
    21. }
    22. glEnd();
    23. }

    Bresenham算法的优点

    • 不用计算斜率,不涉及到浮点数的运算。 

    • 计算中涉及到的全部是整数

    • 乘法运算只有乘以2,可以用移位运算来实现。

  • 相关阅读:
    [mysql] 深入分析MySQL版本控制MVCC规则--实测 (mysql 8.0 innodb引擎)
    大数据高级开发工程师——Spark学习笔记(6)
    uni-app小程序使用DCloud(插件市场)流程
    nginx的location的优先级和匹配方式
    RLChina2022暑期学习-博弈论基础
    prometheus helm install 如何配置告警模版
    2024 年(第 12 届)“泰迪杯”数据挖掘挑战赛—— C 题:竞赛论文的辅助自动评阅完整思路与源代码分享
    1.HTML简介
    深度思考rpc框架面经之五:rpc限流:rpc事务:tps测试
    B站崩了,如果是你是那晚负责的开发人员你会怎么做?
  • 原文地址:https://blog.csdn.net/m0_56494923/article/details/126865683