Bresenham 算法原理
http://wenku.baidu.com/link?url=ova6h39VQ4ilLMIQ51qHpjeuuKu7yLtD1M53NQQc6rUSI9UHymh2r2V8ZZdn6R3bForxZzFf65KO_JCY6flz5A4TU8F4uEHs0N82iCmdQwG
从上面介绍的DDA算法可以看到,由于在循环中涉及实型数据的加减运算,因此直线的生成速度较慢。
在生成直线的算法中,Bresenham算法是最有效的算法之一。Bresenham算法是一种基于误差判别式来生成直线的方法。
一、直线Bresenham算法描述:
它也是采用递推步进的办法,令每次最大变化方向的坐标步进一个象素,同时另一个方向的坐标依据误差判别式的符号来决定是否也要步进一个象素。
我们首先讨论m=△y/△x,当0≤m≤1且x1<x2时的Bresenham算法。从DDA直线算法可知这些条件成立时,公式(2-2)、(2-3)可写成:
xi+1=xi+1 | (2-6) |
yi+1=yi+m | (2-7) |
有两种Bresenham算法思想,它们各自从不同角度介绍了Bresenham算法思想,得出的误差判别式都是一样的。
二、直线Bresenham算法思想之一:
由于显示直线的象素点只能取整数值坐标,可以假设直线上第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 | (2-8) |
d2=(yi+1)-y=(yi+1)-m(xi+1)-b | (2-9) |
这两个距离差是
d1-d2=2m(xi+1)-2yi+2b-1 | (2-10) |
我们来分析公式(2-10):
(1)当此值为正时,d1>d2,说明直线上理论点离(xi+1,yi+1)象素较近,下一个象素点应取(xi+1,yi+1)。
(2)当此值为负时,d1<d2,说明直线上理论点离(xi+1,yi)象素较近,则下一个象素点应取(xi+1,yi)。
(3)当此值为零时,说明直线上理论点离上、下两个象素点的距离相等,取哪个点都行,假设算法规定这种情况下取(xi+1,yi+1)作为下一个象素点。
因此只要利用(d1-d2)的符号就可以决定下一个象素点的选择。为此,我们进一步定义一个新的判别式:
pi=△x×(d1-d2)=2△y·xi-2△x·yi+c | (2-11) |
式(2-11)中的△x=(x2-x1)>0,因此pi与(d1-d2)有相同的符号;
这里△y=y2-y1,m=△y/△x;c=2△y+△x(2b-1)。
下面对式(2-11)作进一步处理,以便得出误差判别递推公式并消除常数c。
将式(2-11)中的下标i改写成i+1,得到:
pi+1=2△y·xi+1-2△x·yi+1+c | (2-12) |
将式(2-12)减去(2-11),并利用xi+1=xi+1,可得:
pi+1= pi+2△y-2△x·(yi+1-yi) | (2-13) |
再假设直线的初始端点恰好是其象素点的坐标,即满足:
y1=mx1+b | (2-14) |
由式(2-11)和式(2-14)得到p1的初始值:
p1=2△y-△x | (2-15) |
这样,我们可利用误差判别变量,得到如下算法表示:
初始 p1=2△y-△x | (2-16) | |
当pi≥0时: yi+1=yi+1, xi+1=xi+1, pi+1=pi+2(△y-△x) |
||
否则: yi+1=yi, |
从式(2-16)可以看出,第i+1步的判别变量pi+1仅与第i步的判别变量pi、直线的两个端点坐标分量差△x和△y有关,运算中只含有整数相加和乘2运算,而乘2可利用算术左移一位来完成,因此这个算法速度快并易于硬件实现。
三、直线Bresenham算法思想之二:
由于象素坐标的整数性,数学点(xi,yi)与所取象素点(xi,yir)间会引起误差(εi),当xi列上已用象素坐标(xi,yir)表示直线上的点(xi,yi),下一直线点B(xi+1,yi+1),是取象素点C(xi+1,yir ),还是D(xi+1,y(i+1)r)呢?
设A为CD边的中点,正确的选择:
若B点在A点上方,选择D点; 否则,选C点。
用误差式描述为:
ε(xi+1)=BC-AC=(yi+1-yir)-0.5 | (2-8') |
求递推公式:
ε(xi+2)=(yi+2-y(i+1)r)-0.5 = yi+1+m-y(i+1)r-0.5 | (2-9') |
当ε(xi+1)≥0时,选D点,y(i+1)r = yir+1
ε(xi+2)= yi+1+m-yir-1-0.5=ε(xi+1)+m-1 | (2-10') |
当ε(xi+1)﹤0时,选C点,y(i+1)r = yir
ε(xi+2)= yi+1+m-yir-0.5=ε(xi+1)+m | (2-11') |
初始时:
ε(xs+1)=BC-AC=m-0.5 | (2-12') |
为了运算中不含实型数,同时不影响不等式的判断,将方程两边同乘一正整数。
令方程两边同乘2·Δx,即d=2·Δx·ε,则:
初始时:
d = 2·Δy-Δx | (2-13') |
递推式:
当d≥0时:{ d=d+2·(Δy-Δx); y++; x++; } 否则: { d=d+2·Δy; x++; } |
(2-14') |
四、直线Bresenham算法实现:
条件:0≤m≤1且x1<x2
1、输入线段的两个端点坐标和画线颜色:x1,y1,x2,y2,color;
2、设置象素坐标初值:x=x1,y=y1;
3、设置初始误差判别值:p=2·Δy-Δx;
4、分别计算:Δx=x2-x1、Δy=y2-y1;
5、循环实现直线的生成:
for(x=x1;x<=x2;x++)
{ putpixel(x,y,color) ;
if(p>=0)
{ y=y+1;
p=p+2·(Δy-Δx);
}
else
{ p=p+2·Δy;
}
}
五、直线Bresenham算法完善:
现在我们修正(2-16)公式,以适应对任何方向及任何斜率线段的绘制。如下图所示,线段的方向可分为八种,从原点出发射向八个区。由线段按图中所示的区域位置可决定xi+1和yi+1的变换规律。
容易证明:当线段处于①、④、⑧、⑤区时,以|△x|和|△y|代替前面公式中的△x和△y,当线段处于②、③、⑥、⑦区时,将公式中的|△x|和|△y|对换,则上述两公式仍有效。
在线段起点区分线段方向
六、直线Bresenham算法演示:
斜率小于1 | 斜率大于1 |
七、直线Bresenham算法特点:
由于程序中不含实型数运算,因此速度快、效率高,是一种有效的画线算法。
八、直线Bresenham算法程序:
void Bresenhamline (int x1,int y1,int x2,int y2,int color) { int x, y, dx, dy, s1, s2, p, temp, interchange, i; x=x1; y=y1; dx=abs(x2-x1); dy=abs(y2-y1); if(x2>x1) if(y2>y1) if(dy>dx) p=2*dy-dx; |
--------------------- 本文来自 DreamSoar 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/kakaxi2222/article/details/50708552?utm_source=copy
Bresenham 算法原理相关推荐
- 详解Bresenham算法原理(1)
今晚心血来潮想起写直线的算法.第一次接直线算法的就是看<Windows游戏编程大师技巧>的时候,它解说了直线光栅化的其中一个快速算法,叫做Bresenham算法,刚开始看的时候以为是什么了 ...
- 图形学-中点Bresenham算法
图形学-中点Bresenham算法 原理 代码 例子 原理 由Bresenham提出的直线生成算法的基本原理是,每次在最大位移方向上走一步,而另一个方向是走步还是不走步取决于误差项的判别. 这时直线将 ...
- Bresenham 画圆算法原理
文章目录 前言 Bresenham 画圆算法原理 两个近似 构造判别式 圆与网格点的关系 关系由来 关系含义 pip_ipi 递推 画圆 程序伪码 圆与网格点的关系图示 前言 首先简要介绍一下生成圆 ...
- bresenham算法_二维光栅图形的扫描:直线的DDA、Bresenham算法与圆的生成
数值微分DDA算法 算法原理 DDA算法是一个增量算法,每一步的x.y值是用前一步的值加上一个增量来获得的,每一步在最大位移方向上加1. 优点:算法直观.易实现 缺点:有浮点数和浮点运算,效率不高 代 ...
- [XJTUSE]计算机图形学第二章作业,使用OpenGL编程实现DDA、中点画线和Bresenham算法和中点画圆法
首先是Windows10 + Visual Studio 2019 搭建OpenGL环境可以查看如下链接: 萌新向!!!Windows10 + Visual Studio 2019 搭建OpenGL环 ...
- 计算机图形学 学习笔记(一):概述,直线扫描转换算法:DDA,中点画线算法,Bresenham算法
前言 本笔记基于 http://www.icourse163.org/learn/CAU-45006?tid=1001746004#/learn/announce 感谢中国农大 赵明老师的分享~ 现在 ...
- bresenham算法模拟游戏中的追踪路线
游戏AI中我们的怪物需要追击我们的玩家,那么怎么样的追击方法更好呢? 对于一般的3D游戏,基本都是动态改变start到target的朝向,然后对转向做一些平滑的插值或者调整,最后再对这个朝向施加相应的 ...
- 圆的扫描转换-中点Bresenham算法
圆的扫描转换是在屏幕像素点阵中确定最佳逼近于理想圆的像素点集的过程.圆的绘制可以使用简单方程画圆算法或极坐标画圆算法,但这些算法涉及开方运算或三角运算,效率很低. 仅包含加减运算的顺时针绘制1/8圆的 ...
- 计算机图形学04:中点Bresenham算法画椭圆
作者:非妃是公主 专栏:<计算机图形学> 博客地址:https://blog.csdn.net/myf_666 个性签:顺境不惰,逆境不馁,以心制境,万事可成.--曾国藩 文章目录 专栏推 ...
最新文章
- 开发Android必知的工具
- 设置系统的viewController modal动画样式
- gorm软删除_gorm踩坑:软删除与某个字段的唯一性
- win下python2,3和pip2,3双版本共存
- Android 注解的使用与注意事项
- 旋转角度_LG推出新款显示器,可多角度旋转
- python 获取进程池 sleeping_Python 进程操作之进程池--Pool
- MySQL Return JSON Value Attributes
- 区块链优秀gitbook资料
- windows 7系统报错txupd.exe
- JS History
- 米小爱团队负责人王刚:语音交互背后,有多少人工就有多少智能
- 3. PSR-3 --- 日志接口
- 企业微信好友和微信好友的区别
- Uclinux、Linux区别
- 【Java】多人协同在线编辑Excel源代码及部署包
- 【群友问题讨论】java类对象数组一些知识盲区
- group by后乱序问题原因和解决
- 汇编:裴波那契数列前50项
- MIDI应用: 播放midi音乐文件的方法 [Win32版本+ C语言版本]
热门文章
- 除了分支管理之外,我想说VisualSVN Server + TortoiseSVN天下无敌
- java date now_Date now=new Date()方法获取时间为什么不对,求大神指教!!!
- 神器来袭,手把手教你使用 Milvus_cli
- 使用python获取股票“已获现金倍数”等“上市公司现金流量”数据
- 【CocosCreator 3.x】使用 RenderTexture 实现 3D 渲染在 UI 上 => 攻略
- 人体模型 java代码_【人体分析-人体关键点识别】-Java示例代码
- PE-RT II型管在保温供热项目中的应用
- dota2输入法无候选框?
- 说说如何使用 IKAnalyzer 实现词频统计并排序
- VMware虚拟机网络设置及hostname设置