绘制任意斜率的直线.docx
- 文档编号:27233969
- 上传时间:2023-06-28
- 格式:DOCX
- 页数:11
- 大小:43.56KB
绘制任意斜率的直线.docx
《绘制任意斜率的直线.docx》由会员分享,可在线阅读,更多相关《绘制任意斜率的直线.docx(11页珍藏版)》请在冰豆网上搜索。
绘制任意斜率的直线
淮海工学院计算机工程学院
实验报告书
课程名:
计算机图形学
题目:
绘制任意斜率的直线
班级:
测绘121
学号:
2012122827
姓名:
王其芳
一、实验目的或要求
1.掌握任意斜率直线的绘制算法。
2.掌握直线中点Bresenham算法的基本原理,能够用VC++实现该算法。
二、实验内容
1、掌握直线段的生成算法,并用C++实现算法,包括中点法生成
直线。
2、编程实现DDA算法、Bresenham算法、中点画线法绘制直线段
三、实验代码
1、生成直线的DDA算法
算法思想:
一个坐标轴上以单位间隔增量,决定另一个坐标轴上最靠近线段路径的对应整数值。
假定x2﹣x1的绝对值大于y2﹣y1的绝对值,取x为一个象素单位长,即x每次递增一个象素,然后利用下式计算相应的y值:
yk+1﹦yk﹢△y﹦yk﹢m·△x
对于|m|>1的线段,可通过计算由Y方向的增量△y引起的改变来生成直线:
xk+1﹦xk﹢△x﹦xk﹢m·△y
生成直线的DDA算法思想是源用初中直线的方程得出来的,而生成直线的中点算法是通过将DDA算法的方程式改为隐函数形式,然后通过与中点的比较确定该取的像素,绘制图线。
/*DDA*/
#include
voidlinedda(intx0,inty0,intx1,inty1,intcolor)
{
intx,dy,dx,y;
floatm;
dx=x1-x0;
dy=y1-y0;
m=dy/dx;
y=y0;
for(x=x0;x<=x1;x++)
{
putpixel(x,(int)(y+0.5),color);
y+=m;
}
}
main()
{
inta,b,c,d,e;
intgraphdriver=DETECT;
intgraphmode=0;
initgraph(&graphdriver,&graphmode,"");
cleardevice();
a=0;
b=100;
c=200;
d=300;
e=200;
linedda(a,b,c,d,e);
getch();
closegraph();
}
运行结果:
VC++环境:
#include
#include
//四舍五入
intRound(floatx)
{
return(int)(x<0?
x-0.5:
x+0.5);
}
//使用DDA算法画任意斜率的直线(包括起始点,不包括终止点)
voidLine_DDA(intx1,inty1,intx2,inty2,intcolor)
{
floatx,y;//当前坐标点
floatcx,cy;//x、y方向上的增量
intsteps=abs(x2-x1)>abs(y2-y1)?
abs(x2-x1):
abs(y2-y1);
x=(float)x1;
y=(float)y1;
cx=(float)(x2-x1)/steps;
cy=(float)(y2-y1)/steps;
for(inti=0;i { putpixel(Round(x),Round(y),color);//在坐标(x,y)处画一个color颜色的点 x+=cx; y+=cy; } } //主函数 voidmain() { initgraph(640,480); //测试画线 Line_DDA(100,100,100,478,RED); //按任意键退出 getch(); } 2、Bresenham直线算法是用来描绘由两点所决定的直线的算法,它会算出一条线段在n维光栅上最接近的点。 这个算法只会用到较为快速的整数加法、减法和位元移位,常用于绘制电脑画面中的直线。 是计算机图形学中最先发展出来的算法。 Bresenham画法与中点法相似,都是通过每列象素中确定与理想直线最近的像素来进行直线的扫描的转换的。 通过各行、各列的象素中心构造一组虚拟网格线的交点,然后确定该列象素中与此交点最近的像素。 该算法的巧妙之处在于可以采用增量计算,使得对于每一列,只需要检查一个误差项的符号,就可以确定该列的所有对象。 根据直线的斜率确定选择变量在X方向上或在Y方向上每次递增一个单位,另一变量的增量为0或1,它取决于实际直线与最近网格点位置的距离,这一距离称为误差。 设第k步的误差为ek,选取上面象素点后的积累误差为: ek+1﹦ek﹢(m﹣1)选取下面的象素点后的积累误差为: ek+1﹦ek﹢m /*Bresenham*/程序代码如下: #include #include //使用Bresenham算法画任意斜率的直线(包括起始点,不包括终止点) voidLine_Bresenham(intx1,inty1,intx2,inty2,intcolor) { intx=x1; inty=y1; intdx=abs(x2-x1); intdy=abs(y2-y1); ints1=x2>x1? 1: -1; ints2=y2>y1? 1: -1; boolinterchange=false;//默认不互换dx、dy if(dy>dx)//当斜率大于1时,dx、dy互换 { inttemp=dx; dx=dy; dy=temp; interchange=true; } intp=2*dy-dx; for(inti=0;i { putpixel(x,y,color); if(p>=0) { if(! interchange)//当斜率<1时,选取上下象素点 y+=s2; else//当斜率>1时,选取左右象素点 x+=s1; p-=2*dx; } if(! interchange) x+=s1;//当斜率<1时,选取x为步长 else y+=s2;//当斜率>1时,选取y为步长 p+=2*dy; } } //主函数 voidmain() { initgraph(640,480); //测试画线 Line_Bresenham(10,100,100,478,BLUE); Line_Bresenham(10,478,638,1,RED); //按任意键退出 getch(); } 运行结果如下: 3、生成直线的中点算法 算法思想: 中点算法主要是利用椭圆的正负划分性,利用已知或以求出的点,根据递推关系来判断下一个点的位置。 中点算法有效地消除了DDA浮点运算效率低下的问题,将直线的斜率m转化为可加的数,然后通过中点来确定要选择的点,这样使得中点算法的效率大大提高,使之成为被图形软件广泛采用的算法之一。 代码如下: #include #include //使用中点算法画任意斜率的直线(包括起始点,不包括终止点) voidLine_Midpoint(intx1,inty1,intx2,inty2,intcolor) { intx=x1,y=y1; inta=y1-y2,b=x2-x1; intcx=(b>=0? 1: (b=-b,-1)); intcy=(a<=0? 1: (a=-a,-1)); putpixel(x,y,color); intd,d1,d2; if(-a<=b)//斜率绝对值<=1 { d=2*a+b; d1=2*a; d2=2*(a+b); while(x! =x2) { if(d<0) y+=cy,d+=d2; else d+=d1; x+=cx; putpixel(x,y,color); } } else//斜率绝对值>1 { d=2*b+a; d1=2*b; d2=2*(a+b); while(y! =y2) { if(d<0) d+=d1; else x+=cx,d+=d2; y+=cy; putpixel(x,y,color); } } } //主函数 voidmain() { initgraph(640,480); //测试画线 Line_Midpoint(100,50,100,478,GREEN); Line_Midpoint(1,478,638,1,BLUE); //按任意键退出 getch(); } 四、实验结果 1、该程序实现了三种算法的直线段绘制 2、比较三种算法的结果: 像素逼近效果由好到差依次为: Bresenham算法、DDA算法、中点算法 执行速度由快到慢依次为: 中点算法、DDA算法、Bresenham算法 五、实验分析与体会 通过此次实验我对计算机图形学有了实际的认识,计算机图形学对我们的生活有很多的益处。 学习之后我知道了计算机图形学是研究怎样利用计算机来显示,生成和处理图形的原理,方法和技术的一门学科。 虽然一开始有些许不懂和茫然,但是经过老师的指导,我还是完成了这次的实验。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 绘制 任意 斜率 直线