DDA算法和Bresenham算法
DDA算法和Bresenham算法
本文结构如下:
- 1、DDA算法
- 2、Bresenham算法
- 3、代码实现核心部分
1、DDA算法
DDA算法是计算机图形学中最简单的绘制直线算法。其主要思想是由直线公式y = kx + b推导出来的。
我们已知直线段两个端点P0(x0,y0)和P1(x1,y1),就能求出 k 和 b 。
在k,b均求出的条件下,只要知道一个x值,我们就能计算出一个y值。如果x的步进为1(x每次加1,即x = x +1),那么y的步进就为k+b;同样知道一个y值也能计算出x值,此时y的步进为1,x的步进为(1-b)/k。根据计算出的x值和y值,向下取整,得到坐标(x’,y’),并在(x’,y’)处绘制直线段上的一点。
为进一步简化计算,通常可令b取0,将起点看作(0,0)。设当前点为(xi, yi)则用DDA算法求解(xi+1,yi+1)的计算公式可以概括为:
- xi+1 = xi + xStep (1)
- yi+1 = yi + yStep (2)
我们一般通过计算 Δx 和 Δy 来确定xStep和yStep:
- 如果 Δx > Δy ,说明x轴的最大差值大于y轴的最大差值,x轴方向为步进的主方向,xStep = 1,yStep = k;
- 如果 Δy> Δx,说明y轴的最大差值大于x轴的最大差值,y轴方向为步进的主方向,yStep = 1,xStep = 1 / k。
根据这个公式,就能通过(xi,yi)迭代计算出(xi+1、yi+1),然后在坐标系中绘制计算出的(x,y)坐标点。
2、Bresenham算法
Bresenham算法也是一种计算机图形学中常见的绘制直线的算法,其本质思想也是步进的思想,但由于避免了浮点运算,相当于DDA算法的一种改进算法。
设直线的斜率为k,当|k| <=1时,x方向为主步进方向;当|k| >1时,y方向为主步进方向。现以|k| <1时为例,推导Bresenham算法的原理。
Bresenham算法直线绘制示意图
图片来自:http://st251256589.blog.163.com/blog/static/16487644920114112817666/
图中绘制了一条直线,蓝色点表示该直线上的点,红色点表示光栅下绘制的点。
假设当前点是(xi,yi)
- 如果int(yi+0.5) = yi,则在点(xi, round(yi))处绘制.
- 如果int(yi+0.5) = yi + 1,则在点(xi, round(yi)+1)处绘制。
上述逻辑可简述为:当x方向是主要步进方向时,以每一小格的中点为界,如果当前的yi在中点(图中红色短线)下方,则y取round(yi); 如果当前的yi在中点上方,则y取rund(yi)+1。
引用部分:现考虑这种方法的误差,因为直线的起始点在像素中心,所以误差项d的初值d0=0。x下标每增加1,d的值相应递增。直线的斜率值k,即d=d+k。一旦d≥1,就把它减去1,这样保证d在0、1之间。当d≥0.5时,最接近于当前像素的右上方像素(x+1,y+1)而当d<0.5时,更接近于右方像素(x+1,y)为方便计算,令e=d-0.5,e的初值为-0.5,增量为k。当e≥0时,取当前像素(xi,yi)的右上方像素(x+1,y+1),而当e<0时,更接近于右方像素(x+1,y)可以改用整数以避免除法。由于算法中只用到误差项的符号,因此可作如下替换:
e1 = 2e * Δx。参考:
http://blog.csdn.net/xdg_blog/article/details/52848891
http://www.cnblogs.com/weiweishuo/archive/2013/03/11/2954443.html
3、代码实现
1、DDA算法
void CGView::DrawDDALine(int startx,int starty, int endx, int endy)
{ CDC* pDC = GetDC();DrawStandLine(pDC);//绘制标准直线int x0 = startx; int y0 = starty ;int x1 = endx; int y1 = endy; int color=RGB(255,0,0);int x; float dx,dy,y,k;dx = x1-x0, dy = y1-y0;k = dy / dx,y = y0;int x2 = startx; int y2 = endx;for(x = x0;x <= x1;x++){ //(20,360)是坐标轴的起点x2 = 20 + x * 30; //30是坐标轴的单位刻度pDC->Ellipse( x2 - 5, y2 - 5, x2 + 5, y2 + 5 );y = k * x + k;y = (int)(y+0.5);y2 = 360 - y * 30;}
}
2、Bresenham算法
void CGView::DrawBresenham(int startx,int starty, int endx, int endy)
{CDC* pDC = GetDC();DrawStandLine(pDC);//绘制标准直线int x0, y0, x1, y1;x0 = startx; y0 =starty;x1 = endx; y1 = endy;int x, y, dx, dy; dx = x1-x0, dy = y1- y0; x = x0;y = y0;double k = dy / dx;//如果 >1,则y方向是主要步进方向,需要转换坐标系方向if(abs(k)>1){Swap(startx,starty,endx,endy);}int e = -dx; int x2 = 20, y2 = 360; //(20,360)是坐标轴的起点for (int x=x0; x<=x1; x++){ pDC->Ellipse( x2 - 5, y2 - 5, x2 + 5, y2 + 5 );x2 += 30;e += 2 * dy;if (e > 0){ y++;y2 -= 30; //30是坐标轴的单位刻度e -= 2*dx;}}
}
两种算法的运行结果情况如下图所示,从图中可已看出,两种算法都能绘制出直线段,但是在细节稍有不同,当x=4时,DDA算法的y值为3,而Bresenham的算法y为2。在不过从效率上看,由于Bresenham避免了浮点运算,所以效率更高。
本文参考了网上的资料,包括图片、文字等。在文中均给出了链接。时间太久了,代码已经找不到出处了。如有疏漏,请指出。
DDA算法和Bresenham算法相关推荐
- 游戏中DDA算法和Bresenham算法的应用
在角色扮演或即时战略游戏中,经常会将角色以最佳的方式走到指定地点.游戏场景的地面情况复杂,而且场面大,若采用盲目式搜索,例如盲目穷举法,则几乎要遍历整个场景,效率非常低,造成角色反应速度过慢,实践证明 ...
- BF算法和KMP算法
给定两个字符串S和T,在主串S中查找子串T的过程称为串匹配(string matching,也称模式匹配),T称为模式.这里将介绍处理串匹配问题的两种算法,BF算法和KMP算法. BF算法 (暴力匹配 ...
- Algorithm:C++语言实现之字符串相关算法(字符串的循环左移、字符串的全排列、带有同个字符的全排列、串匹配问题的BF算法和KMP算法)
Algorithm:C++语言实现之字符串相关算法(字符串的循环左移.字符串的全排列.带有同个字符的全排列.串匹配问题的BF算法和KMP算法) 目录 一.字符串的算法 1.字符串的循环左移 2.字符串 ...
- 操作系统之存储管理——FIFO算法和LRU算法
操作系统之进程调度--优先权法和轮转法(附上样例讲解) 操作系统之银行家算法-详解流程及案例数据 操作系统之多线程编程-读者优先/写者优先详解 操作系统之存储管理--FIFO算法和LRU算法 操作系统 ...
- 若S作主串,P作模式串,试分别写出利用BF算法和KMP算法的匹配过程。
目 录 题目: 百度文库-答案: (1) (2) MOOC标准答案: (1) (2) mooc答案-截图: 数据结构(C语言版)-严蔚敏2007 题目: 设字符串S='aabaabaabaac', ...
- Prim算法和Kruskal算法
Prim算法和Kruskal算法都能从连通图找出最小生成树.区别在于Prim算法是以某个顶点出发挨个找,而Kruskal是先排序边,每次选出最短距离的边再找. 一.Prim(普里姆算法)算法: ...
- 基于Huffman算法和LZ77算法的文件压缩的改进方向
基于Huffman算法和LZ77算法的文件压缩(八) 到这里已经简单实现基于Huffman算法和LZ77算法的文件压缩, GitHub源码:点我 根据基于Huffman算法和LZ77算法的文件压缩(七 ...
- 最短路径Dijkstra算法和Floyd算法整理、
转载自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最短路径-Dijkstra算法和Floyd算法 Dijks ...
- 用Spark学习FP Tree算法和PrefixSpan算法
在FP Tree算法原理总结和PrefixSpan算法原理总结中,我们对FP Tree和PrefixSpan这两种关联算法的原理做了总结,这里就从实践的角度介绍如何使用这两个算法.由于scikit-l ...
- 【Java数据结构与算法】第二十章 Dijkstra算法和Floyd算法
第二十章 Dijkstra算法和Floyd算法 文章目录 第二十章 Dijkstra算法和Floyd算法 一.Dijkstra算法 1.介绍 2.代码实现 二.Floyd算法 1.介绍 2.代码实现 ...
最新文章
- Java---实现运行任意目录下class中加了@MyTest的空参方法(实现图形界面)
- 从用户需求看互联网基础设施服务商www.shzhenai.com
- ruby 反射机制常用方法
- mysql连接nginx_nginx四层负载均衡连接mysql
- mysql国际化_Java的Struts框架中的主题模板和国际化设置
- Nacos自定义扩展的 Data Id 配置
- memcached 安装小结-1
- python 关于excelcsv与cookie的部分笔记
- java多因子认证,Milvus 实战|生物多因子认证系列 (二):人脸识别
- 设计配色专辑,很值得设计师拥有
- proxmoxve打造云桌面_最大亮点!山东众志电子为山东财经大学东方学院打造首个200点位云桌面考场...
- 智能优化算法:蛇优化算法-附代码
- C语言 5个数最值问题
- C# CommandName四个属性
- 使用NGUI实现拖拽功能(拼图小游戏)
- 使用C语言自定义函数计算三角形周长
- 腾讯2018秋招笔试真题(2)
- 如何查看Tomcat是否安装配置成功
- requests使用socks代理
- Sanity Testing 和 Smoke Testing的区别
热门文章
- 无盘工作站建立全攻略
- 临渊羡鱼 不如退而结网
- 【Python】调用WPS V9 API,实现Word转PDF
- (Android-RTC-8)分析HardwareVideoEncoder—BitrateAdjuster
- 西门子主程序调用子程序_西门子PLC调用子程序的方法
- 淘淘商城系列——Solr集群搭建
- 笨方法学python 习题23
- zbb20180815 网盘搜索引擎
- linux宽松模式,三星N9200刷机包 V35.0 自编译官方内核 Selinux置为宽松模式 修复问题 稳定流畅...
- ES6 推荐网络文档书籍