一、             算法原理简介:

算法原理的详细描述及部分实现可参考:

http://www.cs.helsinki.fi/group/goa/mallinnus/lines/bresenh.html

Fig.1

假设以(x, y)为绘制起点,一般情况下的直观想法是先求m = dy /dx(即x每增加1, y的增量),然后逐步递增x, 设新的点为x1 = x + j, 则y1 = round(y + j * m)。可以看到,这个过程涉及大量的浮点运算,效率上是比较低的(特别是在嵌入式应用中,DSP可以一周期内完成2次乘法,一次浮点却要上百个周期)。

下面,我们来看一下Bresenham算法,如Fig. 1,(x, y +ε)的下一个点为(x, y + ε + m),这里ε为累加误差。可以看出,当ε+m < 0.5时,绘制(x + 1, y)点,否则绘制(x + 1, y + 1)点。每次绘制后,ε将更新为新值:

ε = ε + m ,如果(ε + m) <0.5 (或表示为2*(ε + m) < 1)

ε = ε + m – 1, 其他情况

将上述公式都乘以dx, 并将ε*dx用新符号ξ表示,可得

ξ = ξ + dy, 如果2*(ξ + dy) < dx

ξ = ξ + dy – dx, 其他情况

可以看到,此时运算已经全变为整数了。以下为算法的伪代码:

ξ ← 0, y ← y1

For x ← x1 to x2 do

Plot Point at (x, y)

If (2(ξ + dy) < dx)

ξ ←ξ + dy

Else

y ← y + 1,ξ ←ξ + dy – dx

End If

End For

二、             算法的注意点:

Fig. 2

在实际应用中,我们会发现,当dy > dx或出现Fig.2 右图情况时时,便得不到想要的结果,这是由于我们只考虑dx > dy, 且x, y的增量均为正的情况所致。经过分析,需要考虑8种不同的情况,如Fig. 3所示:

当然,如果直接在算法中对8种情况分别枚举, 那重复代码便会显得十分臃肿,因此在设计算法时必须充分考虑上述各种情况的共性,后面将给出考虑了所有情况的实现代码。

三、             算法的实现

以下代码的测试是利用Opencv 2.0进行的,根据需要,只要稍微修改代码便能适应不同环境

//Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/void DrawLine(IplImage *img, int x1, int y1, int x2, int y2)
{int dx = x2 - x1;int dy = y2 - y1;int ux = ((dx > 0) << 1) - 1;//x的增量方向,取或-1int uy = ((dy > 0) << 1) - 1;//y的增量方向,取或-1int x = x1, y = y1, eps;//eps为累加误差
eps = 0;dx = abs(dx); dy = abs(dy); if (dx > dy) {for (x = x1; x != x2; x += ux){SetPixel(img, x, y);eps += dy;if ((eps << 1) >= dx){y += uy; eps -= dx;}}}else{for (y = y1; y != y2; y += uy){SetPixel(img, x, y);eps += dx;if ((eps << 1) >= dy){x += ux; eps -= dy;}}}
}

四、             测试结果

五、             进一步可能的改进

设(x1, y1)为起点,(x2, y2)为终点,取中点(x1 + x2)/2, (y1 +y2)/2,然后从两个端点同时向中点生长,这种并行运算可以提高一定的效率。

原文地址:http://www.cnblogs.com/pheye/archive/2010/08/14/1799803.html

【转】Bresenham快速画直线算法相关推荐

  1. Bresenham快速画直线算法

    现在的计算机的图像的都是用像素表示的,无论是点.直线.圆或其他图形最终都会以点的形式显示.人们看到屏幕的直线只不过是模拟出来的,人眼不能分辨出来而已.那么计算机是如何画直线的呢,其实有比较多的算法,这 ...

  2. C语言快速画直线和画圆的代码

    具体算法的原理我没有深入研究,总之用来快速画直线和画圆是目前很成熟的算法,拿来就用了^-^ 整个算法过程中只用了整数加减和移位,非常适用于运算能力有限的单片机系统. 以下代码只需要把SetPixel替 ...

  3. 图形学画直线c语言,计算机图形学:3种画直线算法(转)

    //--------------------------------------------------------------------- //绘制直线的DDA算法基本函数 //--------- ...

  4. 0.96寸OLED用两点式画直线算法思路分享—代码开源—简单易懂超详细

    这个算法是纯原创,没有任何借鉴的元素 实现原理大概就是通过两个点算出直线方程然后描点 在这个函数中OLED_DrawDot函数是描点函数,如果和自己代码里不匹配可以换成自己代码里的描点函数. 先看整个 ...

  5. photoshop 快速画直线

  6. photoshop 快速画直线 1

  7. 布兰森汉姆画圆matlab,bresenham算法画直线

    实验一名称:基本图形的生成算法 要求:(1)掌握 DDA 生成线段算法 (2)掌握 Bresenham 生成线段算法 (3)掌握生成圆弧算法 1. 代码 (1) Bresenham 画线算法 v 实验 ...

  8. 光栅图形学-画直线经典算法

    光栅图形学算法-画直线算法 如果对这些算法感兴趣,可以去查阅算法的详细介绍,这里只是用伪代码来描述这些算法. 1.DDA算法 DDA算法依赖于直线的斜截式方程 n=x2 - x1; //像素点个数k ...

  9. 计算机图形学E2——OpenGL Bresenham算法画直线

    其他计算机图形学实验见 链接 要求 使用Bresemham算法画直线,并且通过鼠标可以实现交互操作 参考代码: 代码1 代码2 代码3(代码好理解) 代码4(讲解很全面) #include<io ...

最新文章

  1. Failed at the node-sass@4.14.0 postinstall script. npm ERR! This is probably not a problem with npm
  2. C++ 预处理命令#和##用法
  3. warning: rpmts_HdrFromFdno: Header V3 DSA signature: NOKEY, key ID
  4. java log4j权限被否定_SLF4J简介与使用(整合log4j)
  5. 15. 迭代器模式(Iterator Pattern)
  6. 学习 ASP.NET MVC (第二回)实战篇
  7. 【Vue2.0】—默认插槽、具名插槽、作用域插槽(二十四)
  8. 斐波那契数的两种实现方式———1.递归实现,2迭代实现
  9. mysql 大小写敏感设置_MySQL 中的大小写敏感设置
  10. 对CMMI标准的简单理解
  11. Spring源码全解析,帮你彻底学习Spring源码
  12. 微信小游戏 资源下载解压
  13. 微软苏州集体抵制来自阿里、华为的跳槽者:请停止你的“奋斗逼”行为!网友:看到 955 不加班的公司名单,我酸了...
  14. jsp中使用setAttribute发生错误
  15. 巅峰战舰 服务器维护,《巅峰战舰》停止充值关闭服务器公告
  16. 【顺序表】SqList *L是什么意思
  17. This scheduler instance is still active but was recovered by another instanc解决办法
  18. Paper-9 精读VAIL (2019 ICLR)
  19. SpringBoot 中使用HikariPool 报错Possibly consider using a shorter maxLifetime value.
  20. 手机vr玩电脑上的3d游戏以及看视频

热门文章

  1. 20175310 《Java程序设计》第11周学习总结
  2. XCode 项目配置说明
  3. php 学习笔记 数组2
  4. Java并发基础框架AbstractQueuedSynchronizer初探(ReentrantLock的实现分析)
  5. SQL Server性能计数器部署(批量)
  6. 传递闭包(Floyd+bellman-Fold POJ1932)
  7. 1244. Gentlemen
  8. 设置Flex toolTip的样式
  9. 第一篇: 词向量之Word2vector原理浅析
  10. reviewboard搭建