图形学实验报告格式

更新时间:2023-11-14 17:00:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

实验一 直线、圆弧及曲线的生成算法

一、实验目的

1、几种直线生成算法的比较,特别掌握用Bresenham直线生成算法。 2、几种圆弧生成算法的比较,掌握Bresenham圆弧生成算法。 3、掌握用像素点法直接生成其它曲线的方法。

二、基本要求

1、用不同的生成算法在屏幕上绘制出直线的图形,对不同的算法可设置不同的线形或颜色表示区别。

2、用Bresenham生成算法在屏幕上绘制出圆弧的图形,用动画的方式表演图形的生成。

三、算法提示

1、有关直线生成算法有:DDA(数值微分)直线算法、逐点比较法、直线Bresenham生成算法。 直线Bresenham生成算法思想如下(第一象限,且斜率k<1的情况 图2-1 a中的1a):

1) 画点(x1,y1),dx=x2-x1,dy=y2-y1,计算误差初值P1=2dy-dx,i=1;

2) 求直线下一点位置 xi+1=xi+1 如果Pi>0,则yi+1=yi+1,否则 yi+1=yi; 3) 画点(xi+1,yi+1); 4) 求下一个误差Pi+1点,如果Pi>0,则Pi+1=Pi+2dy-2dx,否则 Pi+1=Pi+2dy; 5) i=i+1,如果i

3)只做整数加减运算和乘2运算,而乘2运算可以用移位操作实现。 Bresenham算法的速度很快,并适于用硬件实现。

对于图2-1 a中的2a,只需将xi+1=xi+1改为xi+1=xi-1。

对于图2-1 a中的1b,斜率k>1的情况,可交换变量x和y,y每次长1个单位。对Pi

进行判断,xi+1=xi或xi+1=xi+1。

2、有关圆弧生成算法有:逐点比较法、DDA(数值微分)直线算法、圆的Bresenham生成算法。

圆的生成算法一般将圆划分为8等份,只需计算(90,45)的八分之一圆弧,其它用对称法求得(参见图2-1 b)。

Bresenham生成算法思想如下(第一象限,且斜率k<1的情况): 1) 计算误差初值P1=3-2r,i=1,画点(0,r); 2) 求下一个光栅点位置 xi+1=xi+1 如果Pi<0,则yi+1=yi,否则 yi+1=yi-1; 3) 画点(xi+1,yi+1);

0

0

4) 求下一个误差Pi+1点,如果Pi<0,则Pi+1=Pi+2xi+6,否则 Pi+1=Pi+4(xi-yi)+10; 5) i=i+1,如果x=y则结束操作,否则转步骤2。

圆Bresenham算法的算式简单,只需做加减法和乘4运算

(-y,x)2b2a3ao3b4b1b(x ,y )11(x ,y )22(y,x)1b1a1a4a(-x,y)2a(-x,-y)3a2b(x,y)o3b4b4a(x,-y)(-y,-x)图2-1 a 直线方向的8个象限(y,-x)图2-1 b 圆心在(0,0)点圆周生成时的对称变换 3.对屏幕布局的考虑

适当选取坐标,将屏幕分成几个区域性,在每个区域内实现一种算法,生成一个图形。

也可用delay实现延时实现动画。

四、上机作业题及思考题

1、用正负法编程绘制圆弧

2、用直线Bresenham生成算法绘制直线。 3、用Bresenham生成算法绘制圆。

五、参考源程序

1、 数值微分法生成斜率小于90的直线

/* DDA line 数值微分法生成斜率小于90的直线 */ #include #include \main()

{

int xo,yo,xa,ya,i,j; int dx,dy,c;

float ddx,ddy,x,y; Initialize();

printf(\

scanf(\ /* 输入直线的两个点 */ printf(\ \ scanf(\ printf(\ \ scanf(\

printf(\ if (xa>=xo && xa<=639 && ya>=0 && ya<=yo) /* 数值微分法生成直线算法 */

{

outtextxy(xo,yo+5,\outtextxy(xa,ya-10,\dx=xa-xo; dy=yo-ya;

if (dx>dy) c=dx; else c=dy; ddx=dx*1.0/c; ddy=dy*1.0/c; x=xo*1.0; y=yo*1.0; setcolor(12); line(xo,yo,xa,ya); getch(); while (c>=0) { i=round(x);

j=round(y); putpixel(i,j,14); x=x+ddx; y=y-ddy; c=c-1;

} }

else printf(\ getch(); closegraph(); } int round(ff) float ff; { int k;

if ((ff-(int)ff)>0.5) k=(int)ff+1; else k=(int)ff; k=(int)ff; return(k);

}

2、逐点插补法生成圆弧源程序

/* STEP CIRCLE 逐点插补法生成圆弧 */ #include #include \main() {

int xo,yo,xa,ya,r,l,f; Initialize();

printf(\ /* 输入圆心和半径*/

scanf(\ xa=xo+r; ya=yo;

setcolor(12); circle(xo,yo,r); line(xo-r,yo,xo+r,yo); line(xo,yo-r,xo,yo+r); line(xo,yo,xo+140,yo-140); l=r*1.414/2; f=0; while (l!=0) {

putpixel(xa,ya,14);

putpixel(xa,2*yo-ya,14); putpixel(2*xo-xa,ya,14);

putpixel(2*xo-xa,2*yo-ya,14); putpixel(xo+ya-yo,yo+xa-xo,14); putpixel(xo+ya-yo,yo-xa+xo,14); putpixel(xo-ya+yo,yo+xa-xo,14); putpixel(xo-ya+yo,yo-xa+xo,14); getch();

if (f>=0) {

xa=xa-1;

f=f-2*(xa-xo)+1; } else

{

ya=ya-1;

f=f+2*(yo-ya)+1; l=l-1; } } getch(); closegraph(); }

3、椭圆的生成算法 /*elipse 生成椭圆 */ #include #include \main()

{

Initialize();

draw_ett(180,100,14);

getch();

closegraph(); }

draw_ett(a,b,color) int a,b,color; {int x,y,xo,yo; int l; float f,ff; xo=300; yo=200; x=0; y=b;

f=1.0*b*b+a*a*(-b+0.25); putpixel(xo,yo,12);

while (1.0*b*b*(x+1)<=a*a*(y-0.5)) {

putpixel(x+xo,yo-y,color); if (f<0) {

f=f+1.0*b*b*(2*x+3); x=x+1;}

else {

f=f+1.0*b*b*(2*x+3)+1.0*a*a*(-2*y+2); x=x+1; y=y-1; } }

f=1.0*b*b*(x+0.5)*(x+0.5)+1.0*a*a*(y-1)*(y-1)-1.0*a*b*a*b; while (y>0) {

putpixel(x+xo,yo-y,color); if (f<0)

{

f=f+1.0*b*b*(2*x+2)+1.0*a*a*(-2*y+3); x=x+1; y=y-1;} else {

f=f+1.0*a*a*(-2*y+3); y=y-1; } }

}

本文来源:https://www.bwwdw.com/article/1cmv.html

Top