line划线计算机图像学,【计算机图形学】根本图形元素:直线的生成算法
【计算机图形学】基本图形元素:直线的生成算法
08年9月入学,12年7月毕业,结束了我在软件学院愉快丰富的大学生活。此系列是对四年专业课程学习的回顾,索引参见:http://blog.csdn.net/xiaowei_cqu/article/details/7747205
直线的DDA算法
【算法介绍】
设直线之起点为(x1,y1),终点为(x2,y2),则斜率m为:
直线中的每一点坐标都可以由前一点坐标变化一个增量(Dx, Dy)而得到,即表示为递归式:
并有关系:Dy = m • Dx。递归式的初值为直线的起点(x1, y1),这样,就可以用加法来生成一条直线。具体方法是:
直线方向的8个象限
按照直线从(x1,y1)到(x2,y2)的方向不同,分为8个象限。对于方向在第1a象限内的直线而言,D x=1,D y=m。对于方向在第1b象限内的直线而言,取值Dy=1,Dx=1/m。各象限中直线生成时Dx, Dy的取值列在下表之中。
当|dx|>|dy|时,|D x|=1, |D y|=m;否则:Dx=1/m,|Dy|=1
Dx, Dy的符号与dx, dy的符号相同
这两条规律可以导致程序的简化
【算法流程图】
【相关代码】
void PaintArea::drawLineDDA(QPainter &painter,int x0, int y0, int xEnd, int yEnd)
{
int dx=xEnd-x0,dy=yEnd-y0,steps,k;
float xIncrement,yIncrement,x=x0,y=y0;
if(fabs(dx)>fabs(dy)) steps=fabs(dx);
else steps=fabs(dy);
xIncrement=float(dx)/float(steps);
yIncrement=float(dy)/float(steps);
painter.drawPoint(round(x),round(y));
for(k=0;k
x+=xIncrement;
y+=yIncrement;
painter.drawPoint(round(x),round(y));
}
}
直线的Bresenham算法
这个算法由Bresenham在1965年提出。设直线从起点(x1, y1)到终点(x2, y2)。直线可表示为方程y=mx+b。其中
我们的讨论先将直线方向限于1a象限在这种情况下,当直线光栅化时,x每次都增加1个单元,即
而y的相应增加应当小于1。为了光栅化,yi+1只可能选择如下两种位置之一(如图)。
i+1的位置选择yi-1=yi 或者 yi+1=yi+1
选择的原则是看精确值y与yi及yi+1的距离d1及d2的大小而定。计算式为:
如果d1-d2>0,则yi+1=yi+1,否则yi+1=yi。因此算法的关键在于简便地求出d1-d2的符号。将上公式得
d1-d2=2y-2yi-1=2 (xi+1)-2yi+2b-1
用dx乘等式两边,并以Pi=dx(d1-d2)代入上述等式,得
Pi=2xidy-2yidx+2dy+dx(2b-1)
d1-d2是我们用以判断符号的误差。由于在1a象限,dx总大于0,所以Pi仍旧可以用作判断符号的误差。Pi-1为:
Pi+1=Pi+2dy-2dx(yi+1-yi)
误差的初值P1,可将x1, y1,和b代入式(4)中的xi, yi而得到:
P1=2dy-dx
Bresenham算法的优点是:
不用浮点数,只用整数;
只做整数加减法和乘2运算,而乘2运算可以用硬件移位实现。
Bresenham算法速度很快,并适于用硬件实现。
【算法流程图】
【相关代码】
void PaintArea::drawLineBresenham(QPainter &painter, int x0, int y0, int xEnd, int yEnd)
{
int x,y,dx,dy,e;
if(fabs(x0-xEnd)>fabs(y0-yEnd)){
dx=xEnd-x0; dy=yEnd-y0; e=-dx;
x=x0; y=y0;
for(int i=0;i<=dx;i++)
{painter.drawPoint(x,y);
x=x+1; e=e+2*dy;
if(e>=0) {y=y+1; e=e-2*dx; }}
}
else if(fabs(x0-xEnd)>fabs(y0-yEnd)){
dx=xEnd-x0; dy=yEnd-y0; e=-dx;
x=x0; y=y0;
for(int i=0;i<=dx;i++)
{ painter.drawPoint(x,y);
y=y+1; e=e+2*dx;
if(e>=0) {x=x+1; e=e-2*dy; }}
}
}
中点画线法
假定直线斜率k在0~1之间,当前象素点为(xp,yp),则下一个象素点有两种可选择点(xp+1,yp)或P2(xp+1,yp+1)。若P1与P2的中点(xp+1,yp+0.5)称为M,Q为理想直线与x=xp+1垂线的交点。当M在Q的下方时,则取P2应为下一个象素点;当M在Q的上方时,则取P1为下一个象素点。这就是中点画线法的基本原理。
【算法流程图】
【相关代码】
void PaintArea::drawLineMiddle(QPainter &painter, int x0, int y0, int xEnd, int yEnd)
{
int a,b,d,x,y;
if(fabs(x0-xEnd)>fabs(y0-yEnd)){
a=y0-yEnd; b=xEnd-x0; d=2*a+b; x=x0; y=y0;
painter.drawPoint(x,y);
while(x
{ if(d<0) {x++;y++;d+=2*(a+b); }
else{x++;d+=2*a; }
painter.drawPoint(x,y);
}
}
else if(fabs(x0-xEnd)>fabs(y0-yEnd) &&(x0-xEnd))<0)){
a=y0-yEnd; b=xEnd-x0; d=2*a+b; x=x0; y=y0;
painter.drawPoint(x,y);
while(x>xEnd)
{ if(d<0) {x--;y--; d-=2*(a+b); }
else{x--;d-=2*a; }
painter.drawPoint(x,y);
}
}
else if(fabs(x0-xEnd)
a=y0-yEnd; b=xEnd-x0; d=2*a+b; x=x0; y=y0;
painter.drawPoint(x,y);
while(y>yEnd)
{ if(d<0) {y++;x++;d+=2*(a+b); }
else{y++;d+=2*a; }
painter.drawPoint(x,y);
}
}
else if(fabs(x0-xEnd)0)){
a=y0-yEnd; b=xEnd-x0; d=2*a+b; x=x0; y=y0;
painter.drawPoint(x,y);
while(x>xEnd)
{ if(d<0) {x--;y--; d-=2*(a+b); }
else{x--;d-=2*a; }
painter.drawPoint(x,y);
}
}
else if(fabs(x0-xEnd)0){
a=y0-yEnd; b=xEnd-x0; d=2*a+b; x=x0; y=y0;
painter.drawPoint(x,y);
while(y>yEnd)
{ if(d<0) {y++;x++;d+=2*(a+b); }
else{y++;d+=2*a; }
painter.drawPoint(x,y);
}
}
}
软件截图
这个绘图软件是用QT写的,我会另外写一篇介绍编程结构,敬请期待~
结果分析
此次实验自己真的倾注了很大的心血。
因为很喜欢计算机图形学,所以很想做个像模像样的东西出来,于是就下定决心借实验的机会做个简易的windows画板。也是第一次正式的使用QT开发,摸索的过程使得整个实验拖了很长时间。最终的结果还是比较令自己满意的,至少基本功能都实现了,界面也还看得过去。
过于注重表面,算法上功夫不足,有些“舍本逐末”
我是把整个软件做差不多了,才开始细细得来研究图元的基本算法(开始都是调用qt自带的绘制函数)。调试算法的过程才深刻感觉这比整个软件更花时间(可能因为整个软件并没有很复杂的架构)。由于时间有限,很多地方没有细细改进。尤其是对于k的几种情况,就生生的写了很冗余的代码,实在是丑啊。
以后再继续改进。
要改进的地方还有很多。比如算法结构重构,不要写那么冗余。然后再尝试一些填充算法自己实现,还有自己会试着做做简单的图像处理,变形拉伸什么的。
总之,坚持动手,学以致用。
转载请注明出处:http://blog.csdn.net/xiaowei_cqu/article/details/7762419
5楼a_xiaozhen1小时前好复杂啊!都有点看不懂!Re: xiaowei_cqu1小时前回复a_xiaozhen这是图形学的基础函数,不过一般都不用自己写的4楼hitalex7小时前原来是位技术女~赞!nPS:我是从豆瓣过来的...Re: xiaowei_cqu1小时前回复hitalex原来是位豆友~3楼tomsoft昨天 22:52不错,我一直在研究动态的矢量图形,有几点说明一下:n1)没有作抗锯齿,可以考虑SuperSample算法,使用BoxFilter就足够了,很简单的。n2)实际在真正实现中很多情况会使用ScanLine算法,而非直接这样绘制,如果您在看图形学算法,注意ScanLine算法;Re: xiaowei_cqu9小时前回复tomsoft您说的我没接触过,回头去看一看,谢前辈指点~2楼z1074971432昨天 20:09继续研究画圆,圆弧之类的n直线裁切,我是研究GUI实现时研究的Re: xiaowei_cqu昨天 21:21回复z1074971432嗯,会更新圆的画法1楼yong199105140昨天 15:41师姐,牛b的呢Re: xiaowei_cqu昨天 16:02回复yong199105140 : )
line划线计算机图像学,【计算机图形学】根本图形元素:直线的生成算法相关推荐
- 计算机图形学:Cohen-Sutherland直线段剪裁算法及梁友栋-Barsky裁剪算法(算法原理及代码实现)
一.算法实现原理 Cohen-Sutherland直线段剪裁算法: 算法原理: (1)判断线段两端是否都落在窗口内,如果是,则线段完全可见,否则进行下一步 (2)判断线段两端是否都落在窗口外,如果是, ...
- 华北电力大学计算机图形学实验报告,华北电力大学计算机图形学实验报告分析.doc...
华北电力大学计算机图形学实验报告分析 科 技 学 院 课程设计(综合实验)报告 ( 2013 -- 2014 年度第 2 学期) 实验名称 OpenGL基本图元绘制实验 课程名称 计算机图形学 | | ...
- [转载]一个图形爱好者的书架/白话说学计算机图形学
1.一个图形爱好者的书架 原文地址:http://blog.csdn.net/nhsoft/archive/2004/06/23/22992.aspx 早几天看到有人把自己在大学四年 ...
- 计算机图形动画处理实训报告,西安石油大学计算机图形学 实验报告.doc
文档介绍: 西安石油大学计算机图形学_实验报告实验报告 -计算机图形学实验大作业 课程名称计算机图形学 实验名称二维绘图系统与计算机动画 姓名 学号 专业班级 成绩 指导教师爨莹 实验报告 课程名称计 ...
- 计算机图形学(1)基本图形算法
计算机图形学--基本图形算法 光栅图形中点的表示 屏幕坐标系在左上角 地址=(Xmax-Xmin)[每行像素点数]*(Y-Ymin)[行数]+(X-Xmin)[行中位置]+基地址 直线扫描转换算法 假 ...
- 计算机图形学真实感显示代码,计算机图形学实验 - 真实感图形场景的生成
<计算机图形学实验 - 真实感图形场景的生成>由会员分享,可在线阅读,更多相关<计算机图形学实验 - 真实感图形场景的生成(4页珍藏版)>请在人人文库网上搜索. 1.计算机图形 ...
- 计算机图形学直线线型实验报告,计算机图形学实验报告-直线中点bresenham算法的实现资料.doc...
计算机图形学实验报告-直线中点bresenham算法的实现资料.doc (10页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 29.90 积分 计算机图形 ...
- 计算机图形学01:直线生成算法(DDA算法)
作者:非妃是公主 专栏:<计算机图形学> 博客地址:https://blog.csdn.net/myf_666 个性签:顺境不惰,逆境不馁,以心制境,万事可成.--曾国藩 文章目录 专栏推 ...
- 计算机图形学实验报告 裁剪,计算机图形学-实验报告三-图形裁剪算法
<计算机图形学-实验报告三-图形裁剪算法>由会员分享,可在线阅读,更多相关<计算机图形学-实验报告三-图形裁剪算法(9页珍藏版)>请在人人文库网上搜索. 1.图形裁剪算法1. ...
最新文章
- opensuse使用zypper安装软件
- fancy approach for making your code listed used for short essays, no need for listing in outline
- shell 编程学习笔记(一)
- Ubuntu 用户安装 MATE
- SCNCHECKPOINT
- 深度学习(23)随机梯度下降一: 随机梯度下降简介
- Windows Server 2008 R2 搭建FTP服务
- 语言题库安装包312mb_大学为什么要考取计算机二级,以后很需要,附二级Msoffice题库...
- 谈谈Linux下动态库查找路径的问题
- cygwin/msys: fatal error LNK1104: 无法打开文件“kernel32.lib”
- 软件是指示计算机运行所需的程序,计算机文化基础知识点
- nature 计算机论文,10分钟读懂6篇Nature/Science系列文章
- nanomsg应用中的问题整理
- SqlServer中的Top * With Ties
- 对于最小二乘法的解释
- 2000国家大地坐标系
- 一个简洁的layui主题,可以用于旅游网页的制作
- HDF5 windows编译 release版本、Debug版本
- 微信小程序跳转到H5网页
- 好的用户界面-界面设计的一些技巧
热门文章
- Linux 命令(109)—— ping 命令
- oracle查询表在库中所占空间(表名所有字母必须大写‘table_name’)
- LuoguP2756 飞行员配对方案问题(最大流)
- sscanf 与 sscanf_s的区别
- [转载]网站分析的最基本度量(3)——网站分析工具如何辨别UV
- 2oracle单行函数
- [转]WebGL All in One 全傻瓜简介
- 第一节:创建SpringBoot项目并运行HelloWorld
- Vue单文件项目自定义组件入门
- python27换行_python 27 :用句点字符匹配换行