博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Bresenham快速画直线算法
阅读量:5214 次
发布时间:2019-06-14

本文共 1993 字,大约阅读时间需要 6 分钟。

一、             算法原理简介:

转自pheye

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

    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所示:

 

        

(Fig. 3)

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

三、             算法的实现

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

1 void DrawLine( int x1, int y1, int x2, int y2,uint color) 2 { 3      int dx = x2 - x1; 4      int dy = y2 - y1; 5      int ux = ((dx > 0) << 1) - 1;//x的增量方向,取或-1 6      int uy = ((dy > 0) << 1) - 1;//y的增量方向,取或-1 7      int x = x1, y = y1, eps;//eps为累加误差 8  9      eps = 0;dx = abs(dx); dy = abs(dy); 10      if (dx > dy) 11      {12          for (x = x1; x != x2+ux; x += ux)13          {14               SetPixel(img, x, y);15               eps += dy;16               if ((eps << 1) >= dx)17               {18                    y += uy; eps -= dx;19               }20          }21      }22      else23      {24          for (y = y1; y != y2+uy; y += uy)25          {26               drawPixel(x, y,color);27               eps += dx;28               if ((eps << 1) >= dy)29               {30                    x += ux; eps -= dy;31               }32          }33      }             34 }

四、             测试结果

 

 

 

五、             进一步可能的改进

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

 

 

 

转载于:https://www.cnblogs.com/sky1991/archive/2012/07/09/2583620.html

你可能感兴趣的文章
【Nutch2.2.1基础教程之6】Nutch2.2.1抓取流程 分类: H...
查看>>
Search in Rotated Sorted Array I II
查看>>
三.取消https,直接http访问
查看>>
struts2 过滤器学习
查看>>
解决mvc下使用chosen时根据(data-placeholder)设置缺省值
查看>>
lintcode-201-线段树的构造
查看>>
javaScript| 对象的拷贝
查看>>
WCF第一次调用较慢的问题
查看>>
同余定理
查看>>
为了世界的和平~一起上caioj~~~!
查看>>
loj#6279. 数列分块入门 3
查看>>
MySQL主从配置实现(同一台主机)
查看>>
数组倒序
查看>>
Ubuntu源配置
查看>>
spring boot application.properties
查看>>
input的type属性设为number后可以输入e
查看>>
pdf.js安装步骤和使用
查看>>
bzoj4498: 魔法的碰撞
查看>>
javascript设计模式学习之六——代理模式
查看>>
jquery 图片切换
查看>>