1 算法原理

基本原理从某处摘得:设直线方程为yi+1=yi+k(xi+1-xi)+k。假设列坐标象素已经确定为xi,其行坐标为yi。那么下一个象素的列坐标为xi+1,而行坐标要么为yi,要么递增1为yi+1。是否增1取决于误差项d的值。误差项d的初值d0=0,x坐标每增加1,d的值相应递增直线的斜率值k,即d=d+k。一旦d≥1,就把它减去1,这样保证d在0、1之间。当d≥0.5时,直线与垂线x=xi+1交点最接近于当前象素(xi,yi)的右上方象素(xi+1,yi+1);而当d<0.5时,更接近于右方象素(xi+1,yi)。为方便计算,令e=d-0.5,e的初值为-0.5,增量为k。当e≥0时,取当前象素(xi,yi)的右上方象素(xi+1,yi+1);而当e<0时,取(xi,yi)右方象素(xi+1,yi)。

由于显示直线的像素点只能取整数值坐标,可以假设直线上第i个像素点的坐标为(Xi,Yi),它是直线上点(Xi,Yi)最佳近似,并且Xi=Xi(假设m<1),如下图所示.那么直线上下一个像素点的可能位置是(Xi+1,Yi)或者(Xi+1,Yi+1).

由图可知:在x=Xi+1处,直线上的点y的值是:y=m(Xi+1)+b,该点离像素点(Xi+1,Yi)和像素点(Xi+1,Yi+1)的距离分别为d1和d2。

    d1 = Y - Yi = m(Xi+1)+b - Yi;    (1)

    d2 = (Yi+1) - Y = (Yi+1) - m(Xi+1) - b;    (2)

    两个距离的差是:

    d1-d2 = 2m(Xi+1) - 2Yi + 2b -1;    (3)

  对于公式(3):

  a:当此值为正时,d1>d2,说明直线上理论点离(Xi+1,Yi+1)像素较近,下一个像素点应取(Xi+1,Yi+1);

  b:当此值为负时,d1<d2,说明直线上理论点离(Xi+1,Yi)像素较近,下一个像素点赢取(Xi+1,Yi);

  c:当此值为零时,d1=d2,说明直线上理论点离上、下两个像素点的距离相等,取那个点都行,假设算法规定这种情况下取(Xi+1,Yi+1)作为下一个像素点。

  因此只要利用(d1-d2)的符号就可以决定下一个像素点的选择。需进一步定义一个判别式:

  Pi = △X × (d1-d2) = 2△Y·Xi - 2△X·Yi + c    (4)

    其中△X=(X2-X1)>0,因此Pi与(d1-d2)有相同的符号;

    △Y=Y2-Y1;m=△Y/△X;c=2△Y+△X(2b-1)

  对(4)进一步处理得出误差判别递推公式并消除常数c;

  将(4)中的下标i改为i+1,得到:

  Pi+1 = △X × (d1-d2) = 2△Y·Xi+1 - 2△X·Yi+1 + c  (5)

  假设直线的初始端点恰好是其像素点的坐标,即满足:

  Y1 = mX1 + b ;  (6)

  由公式(4)和(6)得到p1的初始值:

  P1 = 2△Y - △X;  (7)

/*推导过程*/
Pi = △X × (d1-d2) = △Y·Xi - △X·Yi + c ()
Y1 = mX1 + b () P1 = △Y·X1 - △X·Y1 + c
= △Y·X1 - △X·(△Y/△X·X1+b) + c
= △Y·X1 - △Y·X1 - △X·b + c
= c - △X·b
= △Y+△X(2b-) - △X·b
= △Y - △X

  所以可以用误差判别变量,得到如下算法表示:

  初始:P1 = 2△Y - △X  (8)

  当Pi>=0时:Yi+1 = Y+ 1,Xi+1 = X+ 1,Pi+1 = P+ 2(△Y-△X)[根据公式(4)和(5)得出];

/*推导过程*/
Pi = △X × (d1-d2) = △Y·Xi - △X·Yi + c ()
Pi+1 = △X × (d1-d2) = △Y·Xi+1 - △X·Yi+1 + c () ()-()得: Pi+1 = Pi + (△Y·Xi+1)-△Y·Xi - (△X·Yi+1)+△X·Yi ∵ Pi> 时 Yi+1 = Yi + ,Xi+1 = Xi +
∴ Pi+1 = Pi + (△Y·(Xi + ))-△Y·Xi - (△X·(Yi + ))+△X·Yi
= Pi + (△Y-△X)

  否则:Yi+1 = Yi,Xi+1=X+ 1,Pi+1=Pi+2△y[根据公式(4)和(5)得出]

/*推导过程*/
Pi = △X × (d1-d2) = △Y·Xi - △X·Yi + c ()
Pi+1 = △X × (d1-d2) = △Y·Xi+1 - △X·Y(i+1) + c () ()-()得: Pi+1 = Pi + (△Y·Xi+1)-△Y·Xi - (△X·Yi+1)+△X·Yi ∵ Pi> 时 Yi+1 = Yi,Xi+1 = Xi +
∴ Pi+1 = Pi + (△Y·(Xi + ))-△Y·Xi - (△X·(Yi))+△X·Yi
= Pi + △Y

  从(8)式可以看出,第i+1步的判别变量Pi+1仅与第i步的判别变量Pi、直线的两个端点坐标分量差△X和△Y有关,运算中只含有整数相加和乘2运算,而乘2可利用算术左移一位来完成,因此这个算法速度快并易于硬件实现。

  

Bresenham算法的更多相关文章

  1. 《图形学》实验七:中点Bresenham算法画椭圆

    开发环境: VC++6.0,OpenGL 实验内容: 使用中点Bresenham算法画椭圆. 实验结果: 代码: #include <gl/glut.h> #define WIDTH 50 ...

  2. 《图形学》实验六:中点Bresenham算法画圆

    开发环境: VC++6.0,OpenGL 实验内容: 使用中点Bresenham算法画圆. 实验结果: 代码: #include <gl/glut.h> #define WIDTH 500 ...

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

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

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

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

  5. 利用canvas实现的中点Bresenham算法

    Bresenham提出的直线生成算法的基本原理是,每次在最大位移方向上走一步,而另一个方向是走步还是不走步取决于误差项的判别,具体的实现过程大家可以去问度娘.我主要是利用canvas画布技术实现了这个 ...

  6. 通过Bresenham算法实现完成矢量线性多边形向栅格数据的转化

    1.实验目的与要求 目的:通过本次实验,完成矢量线性多边形向栅格数据的转化过程: 要求:采用VC++6.0实现. 2.实验方法 采用Bresenham算法实现 3.实验材料 直线的定义:y = x/3 ...

  7. Bresenham算法画填充圆及SDL代码实现

    画圆是计算机图形操作中一个非常重要的需求.普通的画圆算法需要大量的浮点数参与运算,而众所周知,浮点数的运算速度远低于整形数.而最终屏幕上影射的像素的坐标均为整形,不可能是连续的线,所以浮点数运算其实纯 ...

  8. 基于Bresenham算法画圆

    bresenham算法画圆思想与上篇 bresenham算法画线段 思想是一致的 画圆x^2+y^2=R^2 将他分为8个部分,如上图 1. 只要画出1中1/8圆的圆周,剩下的就可以通过对称关系画出这 ...

  9. bresenham算法的FPGA的实现2

    在上一篇里http://www.cnblogs.com/sepeng/p/4045593.html <bresenham算法的FPGA的实现1>已经做了一个整体框架的布局,但是那个程序只是 ...

  10. bresenham算法的FPGA的实现1

    接着上一篇的 计算实现给出屏幕上任意两个点,求出这两个点之间直线上的所有的点.http://www.cnblogs.com/sepeng/p/4042464.html 这种直接算法的确是被鄙视了 强大 ...

随机推荐

  1. Python reverse()方法--list

    描述 reverse()方法:用于反转列表元素的排列顺序. 语法 语法格式:list.reverse() 参数 NA 返回值 无返回值 实例 #!/usr/bin/python3 a = ['abc' ...

  2. msmq访问格式

    //集群测试,以下格式不行(应是Host映射之类没配置OK) //_MSMQPath = @"FormatName:DIRECT=TCP:msmq496-ha\private$\496-10 ...

  3. Java 基础 IO流之序列化

    一,前言 在前面的IO中,我们都是讲数据以字符串的形式保存.能不能将一个数组保存到文件呢,当取出数据时也是一个数组,如果能够实现那就完美了.我们都知道比较通用的有JSON格式的序列化,那java中也有 ...

  4. 【SpringBoot】springboot -- 2.0版本自定义ReidsCacheManager的改变

    1. 问题发现 在1.0版本中,我们配置redis的cacheManager是这种方式: //缓存管理器 @Bean public CacheManager cacheManager(@Suppres ...

  5. 二维码图片以字符串的形式保存DB,已文件流显示页面上

    以下是生成二维码的方法,我只用其中一个方法 这个需要引用ZXing.DLL 链接:https://pan.baidu.com/s/1mCTwHiAm_awtsPcibAotZw 提取码:ufp6 pu ...

  6. 用matlab画两个曲面的图

    求助!!用matlab画两个曲面的图 这是我写的程序,但是运行不出来,麻烦帮我修改一下,谢谢!!clearallcloseall[x,y]=meshgrid(0:.1:60);z1=(25*y-25* ...

  7. HDU 2196树形DP(2个方向)

    HDU 2196 [题目链接]HDU 2196 [题目类型]树形DP(2个方向) &题意: 题意是求树中每个点到所有叶子节点的距离的最大值是多少. &题解: 2次dfs,先把子树的最大 ...

  8. 获取上一行记录lag

    SELECT EMPLID ,EFFDT ,END_DT ,COMPANY ,DEPTID ,POSITION_NBR ,' ' ,' ' FROM ( SELECT J1.EMPLID ,J1.EF ...

  9. 简单的Json数据

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...

  10. CentOS 7 安装Apache 2.4.39

    使用源码在CentOS 7下安装 apache 2.4.39,之前趟了一遍,简单做个笔记. STEP 1 安装apr STEP 1.1 检查是否安装apr [root@study ~]# yum li ...