一、             算法原理简介:

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

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 > ) << ) - ;//x的增量方向,取或-1
int uy = ((dy > ) << ) - ;//y的增量方向,取或-1
int x = x1, y = y1, eps;//eps为累加误差 eps = ;dx = abs(dx); dy = abs(dy);
if (dx > dy)
{
for (x = x1; x != x2; x += ux)
{
SetPixel(img, x, y);
eps += dy;
if ((eps << ) >= dx)
{
y += uy; eps -= dx;
}
}
}
else
{
for (y = y1; y != y2; y += uy)
{
SetPixel(img, x, y);
eps += dx;
if ((eps << ) >= 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. Bresenham画直线,任意斜率

    function DrawLineBresenham(x1,y1,x2,y2) %sort by x,sure x1<x2. if x1>x2 tmp=x1; x1=x2; x2=tmp; ...

  3. Bresenham直线算法与画圆算法

    在我们内部开发使用的一个工具中,我们需要几乎从 0 开始实现一个高效的二维图像渲染引擎.比较幸运的是,我们只需要画直线.圆以及矩形,其中比较复杂的是画直线和圆.画直线和圆已经有非常多的成熟的算法了,我 ...

  4. Bresenham’s algorithm( 布兰森汉姆算法)画直线

    Bresenham直线算法是用来描绘由两点所决定的直线的算法,它会算出一条线段在 n 维光栅上最接近的点.这个算法只会用到较为快速的整数加法.减法和位元移位,常用于绘制电脑画面中的直线.是计算机图形学 ...

  5. 《图形学》实验五:改进的Bresenham算法画直线

    开发环境: VC++6.0,OpenGL 实验内容: 使用改进的Bresenham算法画直线. 实验结果: 代码: //中点Bresenham算法生成直线 #include <gl/glut.h ...

  6. 《图形学》实验四:中点Bresenham算法画直线

    开发环境: VC++6.0,OpenGL 实验内容: 使用中点Bresenham算法画直线. 实验结果: 代码: //中点Bresenham算法生成直线 #include <gl/glut.h& ...

  7. Python使用DDA算法和中点Bresenham算法画直线

    title: "Python使用DDA算法和中点Bresenham算法画直线" date: 2018-06-11T19:28:02+08:00 tags: ["图形学&q ...

  8. [AlgorithmStaff] Bresenham快速直线算法

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Unity2017.3 | NativeC 最近在学习 Unity tilemap Brush 自定义笔刷功能时候,看到其 ...

  9. 计算机图形学之扫描转换直线-DDA,Bresenham,中点画线算法

    1.DDA算法 DDA(Digital Differential Analyer):数字微分法 DDA算法思想:增量思想 公式推导: 效率:采用了浮点加法和浮点显示是需要取整 代码: void lin ...

随机推荐

  1. SharePoint 网站登录不上,3次输入用户名/密码白页

    新搭建的SharePoint 2013环境,第一次干的这么憋屈的慌,先是接了一个Ghost的服务器,装好的服务器.Sql.SharePoint.VS等一系列,却发现怎么都登陆不上去,输入账号3次以后白 ...

  2. Oracle Spatial中SDO_Geometry详细说明[转]

    在ArcGIS中通过SDE存储空间数据到Oracle中有多种存储方式,分别有:二进制Long Raw .ESRI的ST_Geometry以及基于Oracle Spatial的SDO_Geometry等 ...

  3. 五种创建UIImage的类方法

    五种创建UIImage的类方法 UIImage有五个类方法,用来创建UIImage的.下面介绍一下每个类方法的作用和创建实例. 1.使用类方法imageNamed:创建 + (UIImage *)im ...

  4. 多线程基础(七)GCD线程组+栅栏函数

      1.GCD队列组     拦截通知和等待所有任务全部结束在继续往下执行|阻塞   需求:下载两张图片,等两张图片都下载完毕之后,合成图片(这个实例,复习的时候一定要凭空敲出代码练习,好记性不如烂键 ...

  5. IOS之KVC和KVO(未完待续)

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  6. Windows Server 2012之搭建域控制器DC

    安装域控制器,域(Domain) 1,本地管理员权限 2,设置静态IP 地址 3,至少有一个NTFS分区 4,操作系统版本(web版除外)   设置静态IP地址    dcpromo.exe命令不生效 ...

  7. 【mysql】关于innodb_file_format

    一.几条mysql命令 通过以下命令看一下mysql中 innodb_file_format的配置 mysql> show engines; +--------------------+---- ...

  8. Redis的数据类型及操作

    Strings 最简单的类型,一个Key对应一个Value,string类型是二进制安全的.Redis的string可以包含任何数据,如图片或序列化的对象 操作 Set:设置key对应的值为strin ...

  9. 修改Tomcat服务器的端口号

    关键技术: Connector子元素下的port是设置服务器端口,而connection Timeout则是服务器连接超时单位为毫秒. 操作过程: (1)采用记事本打开Tomcat安装目录下的conf ...

  10. C++ pair用法

    Pair类型概述 pair是一种模板类型,其中包含两个数据值,两个数据的类型可以不同 1.定义(构造): 1 pair<int, double> p1; //使用默认构造函数 2 pair ...