1558.计算机图形学实验报告.doc

上传人:仙人指路1688 文档编号:2391258 上传时间:2023-02-17 格式:DOC 页数:22 大小:1.16MB
返回 下载 相关 举报
1558.计算机图形学实验报告.doc_第1页
第1页 / 共22页
1558.计算机图形学实验报告.doc_第2页
第2页 / 共22页
1558.计算机图形学实验报告.doc_第3页
第3页 / 共22页
1558.计算机图形学实验报告.doc_第4页
第4页 / 共22页
1558.计算机图形学实验报告.doc_第5页
第5页 / 共22页
点击查看更多>>
资源描述

《1558.计算机图形学实验报告.doc》由会员分享,可在线阅读,更多相关《1558.计算机图形学实验报告.doc(22页珍藏版)》请在三一办公上搜索。

1、 计算机图形学实验报告学 院:计算机科学学院 班 级: 学 号: 学生姓名: 指导教师: 2008年1月目录实验一 基本图元的绘制一、实验目的与要求-2二、实验内容-2(一)、简单DDA法画直线-2(二)、Bresenham直线生成算法-4(三)、Bresenham画圆算法-7(四)、角度DDA法产生圆弧-9实验二 自由曲线一、实验目的与要求-11二、实验内容-11(一)、三次参数样条曲线段-11(二)、三次Bezier曲线段-13(三)、三次B样条曲线段-15图形学、CAD二次开发及动画课程设计-17实验一 基本图元的绘制一、实验目的与要求 (1)熟悉TURBO C下图形编辑环境 (2)实现

2、Bresenham算法画直线(3) 设计DDA直线生成算法的实现程序(4)设计Bresenham画圆算法的实现程序(5)设计角度DDA法产生圆弧的实现程序二、实验内容(一)、简单DDA法画直线(1)、算法:在x或y变化大的方向,即计长方向上,步长始终为1,而另一方向上的步长则小于1,其是否走步,视其有无整数部分溢出,也即:若 |k|1,则取xinc =1, yinc =k, yi+1 = yi k ;若 |k|1,则取yinc =1, xinc =1/k, yi+1 = yi 1/k (2)、源程序#include #include #include int ADDline(int k,int

3、 x1,int y1,int x2,int color) int curx,cury,k1;curx = x1;cury = y1;k1 = k;k1 = abs(k1);if (k1 = 1)while(curx!=x2)curx +=1;cury +=k;putpixel(curx,cury,color);else while(curx!=x2) cury +=1;curx +=1/k; putpixel(curx,cury,color); return(0);main() int x1,y1,x2,k; int color = 10; int gdriver=DETECT,gmode;

4、detectgraph(&gdriver,&gmode); initgraph(&gdriver,&gmode,); printf(please input begin:); scanf(%d%d,&x1,&y1); printf(/nplease input end:); scanf(%d%d,&x2,&k); ADDline(k,320+x1,240+y1,320+x2,color); getch(); cleardevice(); closegraph();(3)、运行结果(二)、Bresenham直线生成算法(1)、算法1Bresenham算法画直线:由Bresenham算法的基本原理

5、是每次在最大位移方向上面走一步,而另一个方向上是走步还是不走步取决于误差项的判别。而在误差项的判别是利用中点来判断的,是否走一步,取决于中点的位置,若如果中点在直线上部,则不需要走一步,如果中点在直线下部,则要走一步。其绘图过程为:(1)输入直线的两端点P0(x0,y0)和P1(x1,y1)。(2)计算初始值x, y,d=x-2y,x=x0,y=y0。(3)绘制点(x,y),判断d的符号。若d0,则(x,y)更新为(x+1,y+1),d更新为d+2x2y;否则(x,y)更新为(x+1,y),d更新为d-2y.(4)当直线未画完时,重复步骤(3),否则结束。(2)、源程序#include #in

6、clude #include int Bres_Line(int x1,int y1,int x2,int y2,int color) int oldcolor,iTag; int dx,dy,tx,ty,inc1,inc2,curx,cury,d; putpixel(x1,y1,color); if (x1=x2 & y1=y2) return(1); iTag=0; dx = abs(x2-x1); dy = abs(y2-y1); if(dx0?1:-1;ty=(y2-y1)0?1:-1;curx = x1;cury = y1;inc1 = 2*dy;inc2 = 2*(dy-dx);d

7、=inc1-dx;while(curx!=x2) if (d0) d+=inc1; else cury+=ty; d+=inc2; if(iTag)putpixel(cury,curx,color);elseputpixel(curx,cury,color);curx+=tx;return(0);iSwap(int *a,int *b) int tmp; tmp = *a; *a=*b; *b=tmp;main() int i,j,x1,y1,x2,y2; int color = 15; int gdriver=DETECT,gmode; initgraph(&gdriver,&gmode,)

8、; printf(please input begin(x1,y1):); scanf(%d%d,&x1,&y1); printf(/n please input end(x2,y2):); scanf(%d%d,&x2,&y2); i=20; j=240; moveto(i,j); for(i=20;i=620;i+=20) /*使用双循环画点函数画出表格中的纵坐标*/ lineto(i,240); i=320; j=20; moveto(i,j); for(j=20;j=460;j+=20) /*使用双循环画点函数画出表格中的横坐标*/ lineto(320,j); Bres_Line(x

9、1,y1,x2,y2,color); getch(); closegraph();(3)、运行结果(三)、Bresenham画圆算法(1)、算法设圆的半径为r,考虑圆心在(0,0),从x=0、y=r开始的顺时针方向的1/8圆周的生成过程。在这种情况下,x每步增加1,从x=0开始,到x=y结束,即有xi+1= xi+1;相应的yi+1则在两种可能中选择:yi+1=yi或者yi+1=yi-1。选择的原则是考察精确值y是靠近yi还是靠近yi-1。根据定义可推导出递推公式有:如果di0,选Si,xi=xi-1+1,yi=yi-1,得: di+1=di+4xi-1+6如果di0,选Ti,xi=xi-1+

10、1,yi=yi-1-1,得: di+1=di+4(xi-1-yi-1)+10对于i=1,xi-1=x0=0,yi-1=y0=R,则初值为: d1=3-2R(2)、源程序 #include #include #include #include int Bres_Circle(int x0,int y0,double r,int color) int x,y,d; x=0; y=(int)r; d=(int)(3-2*r); while(xy) CirPot(x0,y0,x,y,color); if(d0) d+=4*x+6; else d+=4*(x-y)+10; y-; x+; if(x=y)

11、CirPot(x0,y0,x,y,color);return(0);int CirPot(int x0,int y0,int x,int y,int color) int oldcolor; putpixel(x0+x),(y0+y),color); putpixel(x0+y),(y0+x),color); putpixel(x0+y),(y0-x),color); putpixel(x0+x),(y0-y),color); putpixel(x0-x),(y0-y),color); putpixel(x0-y),(y0-x),color); putpixel(x0-y),(y0+x),co

12、lor); putpixel(x0-x),(y0+y),color); return(0);main() int i,j,x0,y0,gmode; float r; int color=15; int gdriver=DETECT; initgraph(&gdriver,&gmode,); printf(please input begin(x0,y0):); scanf(%d%d,&x0,&y0); printf(/n please input end(r):); scanf(%f,&r); i=20; j=240; moveto(i,j); for(i=20;i=620;i+=20) /*

13、使用双循环画点函数画出表格中的纵坐标*/ lineto(i,240); i=320; j=20; moveto(i,j); for(j=20;j=460;j+=20) /*使用双循环画点函数画出表格中的横坐标*/ lineto(320,j); Bres_Circle(x0,y0,r,color); getch(); closegraph();(3)、运行结果(四)、角度DDA法产生圆弧(1)、算法若已知圆心坐标为(xc,yc),半径为人,则以角度t为参数的圆的参数方程可写为:x=xc+rcosty=yc+ rsint 当t从0变化到2时,上述方程所表示的轨迹是一整圆;到t从ts变化到te时,则

14、产生一段圆弧。由于我们定义角度的正方向是逆时针方向,所以圆弧是有ts到te逆时针画圆得到的。若给定圆心坐标(xc,yc),半径r及起始角ts和终止角te,要产生ts到te这段圆弧的最主要问题是离散化圆弧,即求出从ts到te所需运动的总步数n。可令:n=(te-ts)/dt+0.5其中,dt为角度增量,即每走一步对应的角度变化。如果用户的给定tets,则可令te=ts+2以保证ts到te是逆时针画圆。如果n=0,则令n=2/dt,即画整圆。(2)、源程序#include #include #include arc1 (int xc,int yc,double r,double ts,double

15、 te) double rad,tsl,tel,deg,dte,ta,ct,st;int x,y,n,i; rad =0.0174533;tsl=ts*rad;tel=te*rad;if(r5.08) deg=0.015;elseif(r7.62)deg = 0.06; elseif(r25.4)deg = 0.075;elsedeg =0.15;dte=deg*25.4/r;if(teltsl)tel+=6.28319; n=(int)(tel-tsl)/dte+0.5);if(n=0)n=(int)(6.28319/dte+0.5);ta=tsl;x=xc+r*cos(tsl);y=yc+

16、r*sin(tsl);moveto(x,y);for(i=1;i=n;i+) ta+=dte; ct=cos(ta); st=sin(ta); x=xc+r*ct; y=yc+r*st; lineto(x,y);x=xc+r*cos(tel); y=yc+r*sin(tel);lineto(x,y);main() int xc,yc; float r,ts,te; int gdriver=DETECT,gmode; initgraph(&gdriver,&gmode,); printf(please input begin(xc,yc)as(xc=320,yc=240):); scanf(%d

17、%d,&xc,&yc); printf(/n please input end(r,ts,te)as(r=100,ts=20,te=200):); scanf(%f%f%f,&r,&ts,&te); arc1(xc,yc,r,ts,te); getch(); closegraph();(3)、运行结果实验二 自由曲线一、实验目的与要求(1)掌握三次三次参数样条曲线、Bezier曲线和B样条曲线生成原理(2)设计三次参数样条曲线、Bezier曲线和B样条曲线程序二、实验内容(一)、三次参数样条曲线段算法如下:每段三次样条曲线都是由其起始点的位置向量P0、P1和起始点处的切线向量P0、P1分解为二

18、维平面的x、y方向的分量,即P0P1P0P12 -2 1 1-3 3 -2 -10 0 1 01 0 0 0P(t)=t3 t2 t 1令=F0(t) F1(t) G0(t) G1(t)P0P1P0P13 -2 1 1-3 3 -2 -10 0 1 01 0 0 0t3 t2 t 1式中 F0(t) =2t3 - 3t2+1(0t1) F1(t) = -2t3 +3t G0(t)=t(t-1) G1(t) =t2(t-1)这组函数称为混合函数。曲线的形状是受曲线段两端点的位置向量和切线向量控制的。当端点的边界条件发生变化时,曲线的形状随之发生变化。(2)源程序下例是绘制一条三次参数样条曲线的程

19、序。程序中,数组px6、py6存放控制点的x,y坐标;数组dx6dy6存放控制点处切线向量的x、y分量;N为每段的等分数。#include #include float px6=50,170,250,310,500,700;float py6=200,220,200,150,200,150;float dx6=100,80,100,300,200,100;float dy6=-100,200,150,-200,-100,100;void Spline() float a0,a1,a2,a3,b0,b1,b2,b3; int k,x,y; float i,t,dt,n=10; setcolor(

20、YELLOW); dt=1/n; for (k=0;k=6-1 ;k+ ) if(getch()=17) exit(); a0=pxk; a1=dxk; a2=-3*pxk+3*pxk+1-2*dxk-dxk+1; a3=2*pxk-2*pxk+1+dxk+dxk+1; b0=pyk; b1=dyk; b2=-3*pyk+3*pyk+1-2*dyk-dyk+1; b3=2*pyk-2*pyk+1+dyk+dyk+1; for(i=0;in;i+=0.1) t=i*dt; x=a0+a1*t+a2*t*t+a3*t*t*t; y=b0+b1*t+b2*t*t+b3*t*t*t; if(i=0)

21、moveto(x,y); lineto(x,y); void main() int driver,mode,i,j; driver=DETECT; i=20; j=240; initgraph(&driver,&mode,); moveto(i,j); for(i=20;i=620;i+=20) /*使用双循环画点函数画出表格中的纵坐标*/ lineto(i,240); i=320; j=20; moveto(i,j); for(j=20;j=460;j+=20) /*使用双循环画点函数画出表格中的横坐标*/ lineto(320,j); printf(press any key to con

22、tinue except Ctrl+Q to quit.n); Spline(); if(getch()=17)exit(); closegraph();(二)、三次Bezier曲线段 三次Bezier曲线的矩阵表达形式如下:P0P1P2P3-1 3 -3 13 -6 3 0-3 3 0 01 0 0 0P(t)=t3 t2 t 14个控制点P0、P1、P2、P3连成的折线多边形称为特征多边形,Bezier曲线的形状是由这个多边形的各个顶点的位置确定的,特征多边形的形状改变,则曲线的形状也就随之改变。(2)源程序程序中,数组px10、py10存放控制点的x,y坐标。#include #incl

23、ude float px10=50,80,120,140,180,230,270,330,380,430;float py10=100,230,230,160,50,50,120,230,230,150;void Bezier() float a0,a1,a2,a3,b0,b1,b2,b3; int k,x,y; float i,t,dt,n=10; setcolor(15); dt=1/n; for(k=0;k10-1;k+) moveto(pxk,pyk); lineto(pxk+1,pyk+1); setcolor(10); for(k=0;k10-3;k+=3) if(getch()=

24、17) exit(); a0=pxk; a1=-3*pxk+3*pxk+1; a2=3*pxk-6*pxk+1+3*pxk+2; a3=-pxk+3*pxk+1-3*pxk+2+pxk+3; b0=pyk; b1=-3*pyk+3*pyk+1; b2=3*pyk-6*pyk+1+3*pyk+2; b3=-pyk+3*pyk+1-3*pyk+2+pyk+3; for (i=0;in ;i+=0.1 ) t=i*dt; x=a0+a1*t+a2*t*t+a3*t*t*t; y=b0+b1*t+b2*t*t+b3*t*t*t; if(i=0) moveto(x,y); lineto(x,y); vo

25、id main() int driver,mode; driver=DETECT; initgraph(&driver,&mode,); printf(press any key to continue except ctrl+Q to quitn); Bezier(); if(getch()=17) exit(); closegraph();(3)、运行结果(三)、三次B样条曲线段三次B样条曲线的矩阵表达式为 P0P1P2P3-1 3 -3 13 -6 3 0-3 0 3 01 4 1 0P(t)=(1/6)*t3 t2 t 1 源程序程序中,px10、py10存放控制点的x,y坐标。#in

26、clude #include float px10=50,90,150,120,220,300,380,320,450,500;float py10=100,60,50,150,240,100,100,200,250,130;void B_spline() float a0,a1,a2,a3,b0,b1,b2,b3; int k,x,y; float i,t,dt,n=10; setcolor(15); dt=1/n; for(k=0;k10;k+) if(k=0) moveto(pxk,pyk); lineto(pxk,pyk); setcolor(10); for(k=0;k10-3;k+

27、) if(getch()=17) exit(); a0=(pxk+4*pxk+1+pxk+2)/6; a1=(pxk+2-pxk)/2; a2=(pxk-2*pxk+1+pxk+2)/2; a3=-(pxk-3*pxk+1+3*pxk+2-pxk+3)/6; b0=(pyk+4*pyk+1+pyk+2)/6; b1=(pyk+2-pyk)/2; b2=(pyk-2*pyk+1+pyk+2)/2; b3=-(pyk-3*pyk+1+3*pyk+2-pyk+3)/6; for(i=0;in;i+=0.1) t=i*dt;x=a0+a1*t+a2*t*t+a3*t*t*t;y=b0+b1*t+b2*

28、t*t+b3*t*t*t;if(i=0) moveto(x,y);lineto(x,y); void main() int driver,mode; driver=DETECT; initgraph(&driver,&mode,); printf(press any key to continue except ctrl+Q to quitn); B_spline(); if(getch()=17) exit(); closegraph();图形学、CAD二次开发及动画课程设计第一部分:1.编写一个AutoLISP程序,其功能是:根据圆心C1、直径D1、D2、D3画三个同心圆如图1所示。程序应

29、提示用户输入C1、D1、D2、D3点的坐标。#include #include #include #include int Bres_Circle(int x0,int y0,double r,int color) int x,y,d; x=0; y=(int)r; d=(int)(3-2*r); while(xy) CirPot(x0,y0,x,y,color); if(d0) d+=4*x+6; else d+=4*(x-y)+10; y-; x+; if(x=y)CirPot(x0,y0,x,y,color);return(0);int CirPot(int x0,int y0,int

30、x,int y,int color) int oldcolor; putpixel(x0+x),(y0+y),color); putpixel(x0+y),(y0+x),color); putpixel(x0+y),(y0-x),color); putpixel(x0+x),(y0-y),color); putpixel(x0-x),(y0-y),color);putpixel(x0-y),(y0-x),color);putpixel(x0-y),(y0+x),color);putpixel(x0-x),(y0+y),color); return(0);main() int x0,y0,gmo

31、de; float r1,r2,r3; int color=15; int gdriver=DETECT; initgraph(&gdriver,&gmode,); printf(please input begin(x0,y0)as(x0=320,y0=240):); scanf(%d%d,&x0,&y0); printf(/n please input R(r1)as(r1=50):); scanf(%f,&r1); printf(/n please input R(r2)as(r2=100):); scanf(%f,&r2); printf(/n please input R(r3)as

32、(r3=150):); scanf(%f,&r3); Bres_Circle(x0,y0,r1,color); Bres_Circle(x0,y0,r2,color); Bres_Circle(x0,y0,r3,color); getch(); closegraph();运行结果2.编写一个AutoLISP程序,其功能是:画一个等腰三角形( P1、p2、P3 ),如图3所示。程序应提示用户输入起始点P 1、长度L 1和角度A。#include #include #include int Bres_Line(int x1,int y1,int x2,int y2,int color) int o

33、ldcolor,iTag; int dx,dy,tx,ty,inc1,inc2,curx,cury,d; putpixel(x1,y1,color); if (x1=x2 & y1=y2) return(1); iTag=0; dx = abs(x2-x1); dy = abs(y2-y1); if(dx0?1:-1;ty=(y2-y1)0?1:-1;curx = x1;cury = y1;inc1 = 2*dy;inc2 = 2*(dy-dx);d=inc1-dx;while(curx!=x2) if (d0) d+=inc1; else cury+=ty; d+=inc2; if(iTag

34、)putpixel(cury,curx,color);elseputpixel(curx,cury,color);curx+=tx;return(0);iSwap(int *a,int *b) int tmp; tmp = *a; *a=*b; *b=tmp;main() int i,j,x1,y1,x2,y2,l; int color = 15; int gdriver=DETECT,gmode; initgraph(&gdriver,&gmode,); printf(please input begin(x1,y1)as(x1=320,y1=240):); scanf(%d%d,&x1,&y1); printf(/n please input long(l)as(l=100):); scanf(%d,&l); i=20; j=240; moveto(i,j); for(i=20;i=620;i+=20) /*使用双循环画点函数画出表格中的纵坐标*/ lineto(i,240); i=320; j=20; moveto(i,j); for(j=20;j=460;j+=20) /*使用双循环画点函数画出表格中的横坐标*/ lineto(320,j); x2=x1+l/2; y2=y1-l/sqrt(2);

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号