|
|---|
作者:
|
|
本次实习是根据高职《计算机图形学》课程教学大纲的要求进行安排的,是为加强本课程理论与实践的关系,培养学生独立工作能力的重要环节,是一次较全面的设计训练。为专业课成及新兴科学技术打下坚实基础。时间共两个教学周(6.18~6.29)。 一.实习目的 1.培养学生综合运用计算机高级语言(C语言)有关课程的知识去分析和解决工程实际问题的能力。以进一步巩固,深化,扩展本课程所学到的理论知识。 2.通过计算机高级语言对图形程序的编写,调试,使学生掌握图形程序编写的一般方法和步骤,以及计算机图形学在机械设计中的应用的基础知识,为以后的专业课程设计,毕业设计及实际工程设计奠定必要的基础,树立理论联系实际的正确设计思想和严谨的工作作风。 3.使学生在编程,绘图,运用设计资料,熟悉有关计算机语言,编程方法,使用经验程序,进行典型绘图和动画程序等方面经受全面的常规基础训练,并且训练同学们在计算机辅助设计方面的基本能力。 二,实习项目及主要内容,时间分配 1.设计题目:设计题目包括: (1)教材例程序2-1至例程序2-11的编写,演示。 2.1金刚石图案 将半径为的R圆周等分成n份,然后用直线将各等分点两两相连,这样形成的图案称之为金刚石图案,其绘图程序如下。
/* 650597 gexun exp2-1.c DIAMOND */ #include<graphics.h> #include<math.h> main() { float t; int x0=320,y0=240; int n,i,j,r,x[50],y[50]; int gdriver=DETECT,gmode; printf("input n(23-31)and r(100-200)\n"); scanf("%d,%d",&n,&r); initgraph(&gdriver,&gmode,"d:\\tc"); cleardevice(); setbkcolor(9); setcolor(4); t=6.28318/n; for(i=0;i<=n;i++) { x[i]=r*cos(i*t)+x0; y[i]=r*sin(i*t)+y0;} for(i=0;i<=n-2;i++) { for(j=i+1;j<=n-1;j++) line(x[i],y[i],x[j],y[j]);} getch();closegraph(); } 本程序简单的调用了直线函数line,通过两点连线绘成。 2.2肾形图案 “肾形图案”是由按某种规律变化的圆形成的:将一个以R为半径的圆周等分成2n份,然后以等分点为圆心,以等分点到对称分割该圆的直径的距离为半径画圆周,则形成肾形图案。肾形图案的绘图程序如下。
/* 650597 gexun exp2-2.ckindney*/ #include<graphics.h> #include<math.h> #define PI 3.1415926 main() { int x,y,r,r1; double a; int gdriver=9,gmode=2; initgraph(&gdriver,&gmode,"d:\\tc"); printf("input radus(<150)\n"); scanf("%d",&r); cleardevice(); setbkcolor(MAGENTA);setcolor(WHITE); for(a=0;a<2*PI;a+=PI/27) {x=r*cos(a)+320;y=r*sin(a)+240; r1=abs(x-320);circle(x,y,r1);} getch();closegraph(); }
2.3海绵图案 整个图案是由大小不同的许多三角形组成的,类似于充满空洞的海绵的切面,称之为海绵图案。在图案中,除了最外面那个大三角形外,其余的三角形都是由连接包含它的三角形的三条边的中点构成的。但是,这种连接三角形的三条边的中点是由选择的。在三角形ABC中,连接3条边的中点形成三角形PQR,这样就最终产生4个小三角形:三角形PQR,APR,PBQ和RQC。在这4个小三角形中,只在其中3个位于角上的小三角形中(即三角形APR,PBQ,RQC)再次连接其3条边的中点形成新的三角形。以后每次分割连线都按这个规则进行,直到一定的深度。可以看到,如果应用递归法来编程绘图,过程会很清楚,且程序工作量又少。而在C语言中,允许函数之间递归调用,这一点对图形设计很有用处。 在绘制该图案的程序中。主体是绘制三角形的函数。这个绘制三角形的函数要成这样的工作:连接三角形的三天边的中点绘制一个三角形,同时又递归调用自身在形成的三个角上的小三角形中连接三条边的中点再次构成新的三角形。 绘制三角形的函数tria如下,其中的形参意义如下: l Xa,ya,xb,yb,xc,yc 三角形三个顶点的坐标; n 递归深度.
/*650597 gexun exp2-3.c RECURSION*/ #include<graphics.h> #include<stdio.h> void tria(xa,ya,xb,yb,xc,yc,n) int xa,ya,xb,yb,xc,yc,n; { int xp,yp,xq,yq,xr,yr; if(n>0) { xp=(xa+xb)/2;yp=(ya+yb)/2; xq=(xb+xc)/2;yq=(yb+yc)/2; xr=(xc+xa)/2;yr=(yc+ya)/2; moveto(xp,yp);lineto(xq,yq); lineto(xr,yr);lineto(xp,yp); tria(xa,ya,xp,yp,xr,yr,n-1); tria(xb,yb,xq,yq,xp,yp,n-1); tria(xc,yc,xr,yr,xq,yq,n-1); } } main() { int n,xa=10,ya=10,xb=10,yb=470,xc=630,yc=470; int gdriver=DETECT,gmode; printf("Input recursion depth(for example,7):"); scanf("%d",&n); initgraph(&gdriver,&gmode,"d:\\tc"); cleardevice(); setbkcolor(9);setcolor(4); moveto(xa,ya);lineto(xb,yb); lineto(xc,yc);lineto(xa,ya); tria(xa,ya,xb,yb,xc,yc,n); getch();closegraph(); }
2.4图形程序 要绘制一个图形,首先要明确绘制这样一个图形需要哪些数据。一般来说,绘制一个唯一确定的图形,需要有两种数据:一种是确定图形形状的数据,称之为形参;另一种是确定图形画在什么地方的位置数据,称之为定位参数。给定了这两组参数,就可以唯一的确定一个任意位置,形状和大小的正多边形。但在绘制程序中,必须把这两组参数转化为具体的绘图用数据。对于正多边形来说,具体的绘图数据就是多边形顶点的坐标,因为只要确定了各顶点,就可以连点成边绘出多边形图案。根据图形学中的几何关系,可以列出计算多边形格顶点坐标的算式。
根据以上的分析和数据的准备,下面便可以着手编写绘制任意正多边形的程序。
/*650597 gexun exp2-4.c POLYGON*/ #include<graphics.h> #include<math.h> void polygon(x0,y0,a,n,af) int x0,y0,a,n; float af; { int x,y,i; float dtheta,theta; if(n<3)return; dtheta=6.28318/n; theta=af*0.0174533; moveto(x0,y0);x=x0;y=y0; for(i=1;i<n;i++) { x=x+a*cos(theta);y=y+a*sin(theta); lineto(x,y);theta=theta+dtheta;} lineto(x0,y0); } main() { int i,a=80,x=200,y=100; int gdriver=DETECT,gmode; initgraph(&gdriver,&gmode,"d:\\tc"); cleardevice(); setbkcolor(9);setcolor(4); for(i=3;i<=10;i++) polygon(x,y,a,i,0.); getch();closegraph(); }
2.5螺旋图案 绘制图案的程序大致可以分为三部分:绘制任意位置和大小的正方形;由正方形及变换构成的方块,把方块规则拼成图案。最后的拼图工作有主程序函数来完成。他所要做的是:计算确定每个方块的定位点坐标,然后相间调用不同螺旋方向的方块。程序如下所列。
/* 650597 gexun exp2-5.c DIAMOND */ #include<graphics.h> #include<math.h> void polygonc(); void block(); main() { int i,j,a,length,n,theta,x=100,y=350; int gdriver=DETECT,gmode; printf("input length,n,theta:"); scanf("%d,%d,%d",&length,&n,&theta); initgraph(&gdriver,&gmode,"c:\\tc"); cleardevice(); setbkcolor(9);setcolor(4); a=length/4; for(i=1;i<=4;i++) { for(j=1;j<=4;j++) { block(x,y,a,n,theta); theta=-theta;x=x+a;} x=100;y=y-a;theta=-theta;} getch();closegraph(); } void polygonc(x0,y0,r,n,af) int x0,y0,n,r; float af; { int x,y,xs,ys,i; float dtheta,theta; if(n<3) return; dtheta=6.28318/n;theta=af*0.0174533; xs=x0+r*cos(theta);ys=y0+r*sin(theta); moveto(xs,ys); for(i=1;i<n;i++) { theta=theta+dtheta;x=x0+r*cos(theta); y=y0+r*sin(theta);lineto(x,y);} lineto(xs,ys); } void block (x,y,a,n,theta) int x,y,a,n,theta; { int x0,y0,i,r; float t,f,af=45.; t=fabs(theta*0.0174533);f=1.0/(cos(t)+sin(t)); r=a/1.414;x0=x+0.5*a;y0=y+0.5*a; for(i=1;i<=n;i++) { polygonc(x0,y0,r,4,af); r=r*f;af=af-theta;} } 2.6 典型绘图方法 1 参数法绘图 实际生产活动中,存在着大量相同类型的构件。在同一类型中,构件结构相似,在图形中,具体形状的差别往往可由少数参数来确定。因此,这些图形利用参数法绘图比较容易。我们以螺栓的绘图为例,来说明参数法绘图的方法:首先进行图形分析,然后确定绘图数据,最后编写绘图程序。程序如下例:
/* gexun exp2-6.c BOLT */ #include<graphics.h> #include<math.h> void bolt(x0,y0,d,l) int x0,y0,d,l; { int x1,x2,x3,x4,x5,x6,x7,x8,y1,y2,y3,y4,y5,r1,r2,b,c; if(l>2*d)b=2*d; else b=l; r1=1.5*d;r2=0.38*d;c=0.1*d;x1=x0-0.7*d; x2=x0-0.61*d;x3=x0-0.32*d;x4=x0+0.8*d; x5=x0+l-b;x6=x0+l-c;x7=x0+l-0.05*d;x8=x0+l; y1=d;y2=0.75*d;y3=0.5*d;y4=0.425*d;y5=0.4*d; setlinestyle(0,0,3); moveto(x2,y0-y3);lineto(x6,y0-y3); lineto(x8,y0-y5);lineto(x8,y0+y5); lineto(x6,y0+y3);lineto(x2,y0+y3); moveto(x2,y0-y1);lineto(x0,y0-y1); lineto(x0,y0+y1);lineto(x2,y0+y1); moveto(x1,y0+y2);lineto(x1,y0-y2); moveto(x5,y0+y3);lineto(x5,y0-y3); moveto(x6,y0+y3);lineto(x6,y0-y3); arc(x3,y0-y2,140,220,r2); setlinestyle(0,0,3); arc(x3,y0+y2,140,220,r2); setlinestyle(0,0,3); arc(x4,y0,160,220,r1); setlinestyle(0,0,1); moveto(x5,y0-y4);lineto(x7,y0-y4); moveto(x5,y0+y4);lineto(x7,y0+y4); setlinestyle(2,0,1); moveto(x1-20,y0);lineto(x8+20,y0); } main() { int a0,b0,c,d; int gdriver=DETECT, gmode; printf("Input four number\n"); scanf("%d,%d,%d,%d",&a0,&b0,&c,&d); initgraph(&gdriver,&gmode,"c:\\tc"); cleardevice(); setbkcolor(9);setcolor(4); bolt(a0,b0,c,d); getch();closegraph(); } 2.7子程序拼接法绘 有些图形例如阶梯轴,不能用参数法来绘制,因为一个阶梯轴所包含的轴段数,每个轴段的直径,长度和形状等是没有固定的相互干系的,也就是说不存在比例关系。因此,利用子图形拼接法画就比较容易:首先进行图形分析,接下来就可以进行程序设计了。具体程序实例如下例。
/* 650597 gexun exp2-7.c DIAMOND */ #include <graphics.h> #include<stdio.h> void shaftr(x0,y0,d,l,r,k) int x0,y0,d,l,r,k; { int x1,x2,y1,y2,y3,y4,af; x1=x0+k*l;x2=x0+k*(l-r); y1=y0+k*(d/2+r);y2=y0+k*d/2; y3=y0-k*d/2;y4=y0-k*(d/2+r); af=(1-k)*90;arc(x2,y1,af,af+90,r); moveto(x2,y2);lineto(x0,y2); lineto(x0,y3);lineto(x2,y3); arc(x2,y4,af-90,af,r); } main() { int x0,y0,d,l,r,k; int gdriver=DETECT,gmode; printf("input x0,y0,d,l,r,k:"); scanf("%d,%d,%d,%d,%d,%d",&x0,&y0,&d,&l,&r,&k); initgraph(&gdriver,&gmode,"d:\\tc"); cleardevice(); setbkcolor(9);setcolor(4); shaftr(x0,y0,d,l,r,k); getch();closegraph(); } 2-8 子程序二: /* 650597 gexun exp2-8.c DIAMOND */ #include<graphics.h> #include<stdio.h> void keygroove(x0,y0,b,l,k) int x0,y0,b,l,k; { int r,x1,x2,y1,y2,af1,af2; r=b/2; x1=x0+k*r;y1=y0-k*r; x2=x0+k*(l-r);y2=y0+k*r; af1=k*90;af2=af1+180; arc(x1,y0,af1,af2,r); moveto(x1,y2);lineto(x2,y2); arc(x2,y0,af2,af1,r); moveto(x2,y1);lineto(x1,y1); setlinestyle(2,0,1); moveto(x1,y0-r-5);lineto(x1,y0+r+5); moveto(x2,y0-r-5);lineto(x2,y0+r+5); setlinestyle(0,0,1); } main() { int x0,y0,b,l,k; int gdriver=DETECT,gmode; printf("input x0,y0,b,l,k:"); scanf("%d,%d,%d,%d,%d",&x0,&y0,&b,&l,&k); initgraph(&gdriver,&gmode,"d:\\tc"); cleardevice(); setbkcolor(9);setcolor(4); keygroove(x0,y0,b,l,k); getch();closegraph(); } 2.9 动画程序 动画的原理是用一组相关的画片连续更替,当这种更替达到一定的速度时,就能产生画面动起来的效果,它的制作过程是,把一个运动过程按时间的先后分解成多步,把每一个制作成一张画片;当把这些相关的画片按次序快速替换时,人们的视觉感受是:整个运动过程是连续的。 依照动画制作的原理,可以编程实现在屏幕上不断清除掉原有的图形,又在新的位置上画出新的后续图形。快速重复上述过程,就能使整个屏幕上的画面产生动起来的效果,利用重画技术产生的动画的程序见下。 /* 650597 gexun exp2-9.c DIAMOND */ #include<graphics.h> #define TIME 1000 /*The function to paint MOON*/ void moon(x,y,r) int x,y,r; { setcolor (WHITE); arc(x,y,-120,120,r);arc(x-0.5*r,y,-90,90,0.87*r); setfillstyle(SOLID_FILL,WHITE); floodfill(x+0.5*r,y,WHITE); return; } /*The function to paint a CAR*/ void car(dx,color,nu,p) int dx,color,nu,*p; { int i; for(i=0;i<2*nu;i+=2) *(p+i)=*(p+i)+dx; setcolor(color);setfillstyle(SOLID_FILL,color); fillpoly(nu,p);setfillstyle(SOLID_FILL,DARKGRAY); fillellipse(*p+15,350,10,10);fillellipse(*p+65,350,10,10); return; } main() { int pcar[9][2]={5,350,90,350,90,335,70,335,65,320,25,320,20,335,5,335,5,350}; int road[5][2]={0,360,0,479,639,479,639,360,0,360}; int i; int gdriver=DETECT,gmode; initgraph (&gdriver,&gmode,"d:\\tc"); cleardevice(); setbkcolor(LIGHTBLUE);setfillstyle(SOLID_FILL,GREEN); fillpoly(5,*road);moon(480,120,50);car(5,RED,9,pcar); settextstyle(TRIPLEX_FONT,HORIZ_DIR,4); outtextxy(40,40,"PRESS ANY KEY TO START"); getch(); /*Next program to complete a motion*/ for(i=0;i<54;i++) { cleardevice(); setfillstyle(SOLID_FILL,GREEN); fillpoly(5,*road); moon(480-6*i,120,50);/*The Moon to left*/ car(10,RED,9,pcar);/*The car to right*/ delay(TIME); } outtextxy(100,400,"PRESS ANY KEY TO RETURN"); getch();closegraph(); } 2.10 利用多页图形功能设计动画程序 在用重画技术产生的动画中,程序每次都要把整屏画面实时更新,亦即当场作画。如果画面比较复杂,那么这种实时更新费时多,必然会破坏整个动画过程的连续感有些图形卡,比如和,可以支持多个图形页。这些页可分别用于作图和显示。用多图形页功能来实现动画的程序见下。
/* 650597 gexun exp2-10.c DIAMOND */ #include<graphics.h> #define TIME 100 void moon(x,y,r) int x,y,r; { setcolor(WHITE); arc(x,y,-120,120,r);arc(x-0.5*r,y,-90,90,0.87*r); setfillstyle(SOLID_FILL,WHITE); floodfill(x+0.5*r,y,WHITE); return; } void car(dx,color,nu,p) int dx,color,nu,*p; { int i; for(i=0;i<2*nu;i+=2) *(p+i)=*(p+i)+dx; setcolor(color);setfillstyle (SOLID_FILL,color); fillpoly(nu,p);setfillstyle (SOLID_FILL,DARKGRAY); fillellipse(*p+15,295,10,10);fillellipse(*p+65,295,10,10); return; } main() { int pcar[9][2]={5,290,90,290,90,275,70,275,65,260,25,260,20,275,5,275,5,290}; int road[5][2]={0,300,0,349,639,349,639,300,0,300}; int i; int gdriver=VGA,gmode=VGAMED; initgraph(&gdriver,&gmode,"d:\\tc"); cleardevice(); setbkcolor(LIGHTBLUE);setfillstyle(SOLID_FILL,GREEN); fillpoly(5,*road);moon(480,90,50);car(5,RED,9,pcar); settextstyle(TRIPLEX_FONT,HORIZ_DIR,4); outtextxy(40,20,"PRESS ANY KEY TO START"); getch(); for(i=0;i<108;i++) { if((i&1)==0) {setvisualpage(0);delay(TIME); setactivepage(1); cleardevice(); setfillstyle(SOLID_FILL,GREEN); fillpoly(5,*road); moon(480-3*i,90,50); car(5,RED,9,pcar); } else {setvisualpage(1);delay(TIME); setactivepage(0); cleardevice(); setfillstyle(SOLID_FILL,GREEN); fillpoly(5,*road); moon(480-3*i,90,50); car(5,RED,9,pcar);}} outtextxy(100,310,"PRESS ANY KEY TO RETURN"); setvisualpage(0); getch();closegraph();} 2.11 在上面介绍的两个例子中,动画中连续相邻的两个画面中的后续画面,都是要重新绘制整幅图形。其实在运动的过程中,连续的相邻两个画面之间,变化是比较小的,发生运动的只是其中的部分内容,而其他部分是不变化的,这就是相邻换面之间存在的“空间相关性”。 1.程序设计思路 Turbo C中有两个函数getinage 和putimage,是用于存取和输出屏幕位图像信息的。其中,getimage函数的功能是将屏幕上指定区域中的一个位图像信息取下并存到内存中;putinage函数的功能是将内存中的位图像按指定的方式输出到屏幕上指定的位置上。这两个函数的调用方法如下: 1).getimage的调用方法 Gerimage(x1,yt,xr,yb,*bitmap); 其中形参的意义如下: &O1548; x1,yt,xr,yb 整形变量,指定位图所在的矩形区域的对角点坐标; &O1548; *bitmap 内存中存放位图信息的地址。 2).putimage调用方法 .putimage(x,y,*bitmap,op); 其中形参的意义如下: &O1548; x,y 整形变量,指定图像在屏幕上输出位置的定点坐标(矩形左上角定点)。 &O1548; * bitmap 同 getimage 函数。 &O1548; Op 为位图像的输出方式,其职和含义如下: COPY PUT(0) 复制 XOR PUT(1) 异或 OR PUT(2) 或 AND PUT(3) 与 NOT PUT(4) 复制源图像的非 在程序中,可以先画出汽车和月亮,并用函数getimage把汽车和月亮的位图像去存到内存中。然后用putimage函数,把已存在内存中的汽车和月亮的图像顺序复制到屏幕上不断变化着的新位置上,结果就产生了动画的效果。 2.程序:用图像处理函数生成的程序见下。 /* 650597 gexun exp2-11.c DIAMOND */ #include<graphics.h> #include<stdlib.h> #include<alloc.h> #include<dos.h> #define TIME 100 main() { int pcar[9][2]={5,350,90,350,90,335,70,335,65,320,25,320,20,335,5,335,5,350}; int road[5][2]={0,360,0,479,639,479,639,360,0,360}; int sky[5][2]={10,40,10,72,455,72,455,40,10,40}; int i,carcolor=RED; void *carsize,*moonsize; int gdriver=DETECT,gmode; initgraph(&gdriver,&gmode,"c:\\tc"); cleardevice(); setbkcolor(LIGHTBLUE);setcolor(GREEN); setfillstyle(SOLID_FILL,GREEN); fillpoly(5,*road); /*The function to paint Moon*/ setcolor(WHITE); arc(480,90,-120,120,50);arc(455,90,-90,90,44); setfillstyle(SOLID_FILL,WHITE); floodfill(505,90,WHITE); /*The function to paint a CAR*/ setcolor(carcolor); setfillstyle(SOLID_FILL,carcolor); fillpoly(9,*pcar); setfillstyle(SOLID_FILL,DARKGRAY); fillellipse(pcar[0][0]+15,350,10,10); fillellipse(pcar[0][0]+65,350,10,10); /*take two images of car and moon*/ moonsize=malloc(imagesize(450,40,540,140)); carsize=malloc(imagesize(0,320,90,360)); getimage(455,40,540,140,moonsize); getimage(0,320,90,360,carsize); settextstyle(TRIPLEX_FONT,HORIZ_DIR,4); outtextxy(10,40,"PRESS ANY KEY TO START"); getch(); /*clear a string*/ setcolor(LIGHTBLUE); setfillstyle(SOLID_FILL,LIGHTBLUE); fillpoly(5,*sky); /*Next program to complete a motion*/ for(i=1;i<=100;i++) { putimage(455-3*i,40,moonsize,COPY_PUT); putimage(5*i,320,carsize,COPY_PUT); delay(TIME); } setcolor(RED); outtextxy(100,400,"PRESS ANY KEY TO RETURN"); getch(); free(carsize);free(moonsize); closegraph(); } (2) 自行编制独立的程序,要求每学生独立至少完成.两个典型程序,并完成演示,图形输出打印.(可参照课本P200附录A练习题,或自行完成确定内容,如剖面线填充,直线段裁剪,三次样条曲线,Bezier曲线,B样条曲线,动画程序,典型零件程序等) 自行编制程序一: /*===============================================*/ /* 程序说明:用c语言实现自行车动画 */ /* written by gexun */ /* 说明:本程序在tc3.0下调试通过 */ /*===============================================*/ #include<stdlib.h> #include<graphics.h> #include<conio.h> #include<dos.h> #include<stdio.h> void main() { int gdriver=DETECT,gmode,errorcode; int x,y,x1; int buf1[3000],buf2[3000]; initgraph(&gdriver,&gmode,"d:tc3bgi"); errorcode=graphresult(); if(errorcode!=grOk) { printf("Graphics error:%sn",grapherrormsg(errorcode)); printf("Press any key to halt:"); getch(); return; } x=getmaxx();y=getmaxy(); x1=x; line(0,y/2+74,x,y/2+74); circle(x/2,y/2,10); line(x/2,y/2+10,x/2+5,y/2+38); line(x/2+5,y/2+38,x/2-5,y/2+52); line(x/2-5,y/2+52,x/2+10,y/2+65); line(x/2+5,y/2+38,x/2,y/2+54); line(x/2,y/2+54,x/2+8,y/2+70); line(x/2,y/2+10,x/2-15,y/2+30); line(x/2,y/2+10,x/2-1,y/2+25); line(x/2,y/2+25,x/2-10,y/2+32); line(x/2-16,y/2+29,x/2-9,y/2+33); line(x/2-12,y/2+31,x/2-12,y/2+40); line(x/2+20,y/2+40,x/2-12,y/2+40); line(x/2+20,y/2+40,x/2+22,y/2+60); line(x/2-12,y/2+40,x/2-14,y/2+60); circle(x/2-14,y/2+60,14); circle(x/2+22,y/2+60,14); getimage(x/2-40,y/2-10,x/2+50,y/2+73,buf1); getch(); putimage(x/2-40,y/2-10,buf1,XOR_PUT); while(!kbhit()) { putimage(x1-90,y/2-10,buf1,XOR_PUT); delay(200); putimage(x1-90,y/2-10,buf1,XOR_PUT); x1=x1-10; if(x1<0) x1=x; }
closegraph();
}
自行编制程序二: /*===============================================*/ /* 程序说明:c语言实现火箭动画 */ /* written by gexun */ /* 说明:本程序在tc3.0下调试通过 */ /*===============================================*/ 程序运行后会在屏幕上用triplex_font显示“press any key for set off”,下方是用基本的线条画出的发射架,即程序中的DrawGun()函数,当按下任意键后,将在发射架上方出现一个用横线填充的飞机,同时背景被繁星填充,此时必须按住任意键不放,否则飞机将不会发射。发射完成后,即飞机坐标小于0,将出现一句话:"successfully!!!,press ESC to quit",若中途按ESC退出,则飞机Y坐标不小于0,将出现"failue,..."这句话。 #include<graphics.h> #include<conio.h> #include<stdio.h> #include<stdlib.h> #include<alloc.h>
#define ESC 0x1b/*ESC的ASCII码,十六进制*/
void InstallGraph(void);/*图形程序加载函数的说名语句*/ void DrawGun(void); /*画发射架函数的说明语句*/ void DrawPlan(void); /*画飞机函数的说明语句*/ void DrawStar(void); /*画星函数的说明语句*/
void *buf; /*全局变量,用于存储飞机的图像*/ int x0=300; /*以下是飞机的位置初始化参数*/ int y0=340; int width1=5; int width2=20; int height=25; int y1=8; int y2=15; int y3=23; int y4=38;
/*主函数开始*/ main() { int size; int i=0; int key; int station;
InstallGraph(); setbkcolor(BLACK); cleardevice();/*图形驱动程序和屏幕初始化工作完成*/
setcolor(BLUE);/*设置字的颜色*/ settextstyle(TRIPLEX_FONT,0,4);/*设置字体*/ outtextxy(80,100,"Ready!...Any key to SET OFF !!!"); DrawGun(); /*画出发射架*/ getch(); /*if press key,clear the words and start*/
cleardevice(); DrawGun(); DrawPlan(); DrawStar(); setcolor(LIGHTRED);/*define result words color*/
do{ /*程序主循环开始,用于运动飞机,方法是用异或的方式在屏幕上连续画出飞机的图像,每画一次,新图像和来的位置相差两个像素点。 这个值是可调的,值越大,飞机飞行的速度越快*/
putimage(x0-width2,y0-height-3*width1-i,buf,XOR_PUT); i+=2; putimage(x0-width2,y0-height-3*width1-i,buf,XOR_PUT);
key=getch(); if(y0-height-3*width1-i==0) outtextxy(60,100,"Successfully!!! Press ESC to quit"); if(key==ESC){ if(y0-height-3*width1-i>0){ cleardevice(); outtextxy(100,100,"Failue. What did you do?"); outtextxy(130,300,"Press any key to quit."); getch(); } }
}while(key!=ESC);
free(buf); closegraph(); return 0;
} /*****************Install the graphics library***********************/
void InstallGraph(void) { int grdriver=DETECT; int grmode; int errorcode; char *errormsg;
registerbgidriver(VGA); registerbgifont(TRIPLEX_FONT); initgraph(&grdriver,&grmode,"");
errorcode=graphresult(); errormsg=grapherrormsg(errorcode); if(errorcode!=grOk){ printf("Graphics error: %s\n",errormsg); printf("Press any key to exit.\n"); getch(); exit(1); } }
/************************Draw the star ********************************/
void DrawStar(void) { int seed=2000; int i,dotx,doty,height,width,color,maxcolor;
maxcolor=getmaxcolor(); width=getmaxx(); height=getmaxy();
srand(seed); for(i=0;i<250;i++){ dotx=i+random(width-1); doty=i+random(height-1); color=random(maxcolor);
setcolor(color); putpixel(dotx,doty,color); circle(dotx+1,doty+1,1);
} srand(seed); } /****************Draw the bottom gun********************/ void DrawGun(void) { int x0=300; int y0=430; int height=45; int rx=20; int ry=5; int rightx,righty,leftx,lefty; int centery1=30; rightx=righty=leftx=lefty=12;
setcolor(LIGHTGREEN); ellipse(x0,y0,180,360,rx,ry); ellipse(x0,y0-height,0,360,rx,ry); line(x0+rx,y0,x0+rx,y0-height); line(x0-rx,y0,x0-rx,y0-height);
moveto(x0+rx,y0); lineto(x0+rx+rightx,y0+righty); moveto(x0+rx+rightx,y0+righty); lineto(x0+rx+rightx+10,y0+righty+10); circle(x0+rx+rightx+10,y0+righty+10,4);
moveto(x0,y0+ry); lineto(x0,y0+centery1); moveto(x0,y0+centery1); lineto(x0,y0+centery1+10); circle(x0,y0+centery1+10,4);
moveto(x0-rx,y0); lineto(x0-rx-leftx,y0+lefty); moveto(x0-rx-leftx,y0+lefty); lineto(x0-rx-leftx-10,y0+lefty+10); circle(x0-rx-leftx-10,y0+lefty+10,4);
line(x0-rx-leftx,y0+lefty,x0,y0+centery1); line(x0,y0+centery1,x0+rx+rightx,y0+righty); } /*****************Draw the plan fly to the sky***********************/ void DrawPlan(void) {
int size;
setcolor(LIGHTRED); setfillstyle(1,BLUE); ellipse(x0,y0-height,0,180,width1,3*width1);
moveto(x0+width1,y0); /*moveto center right side*/ lineto(x0+width1,y0-height); moveto(x0+width1,y0); lineto(x0+width2,y0+y2);
moveto(x0-width1,y0); /*moveto center left side*/ lineto(x0-width1,y0-height); moveto(x0-width1,y0); lineto(x0-width2,y0+y2);
moveto(x0+width2,y0+y3);/*moveto right bottom side*/ lineto(x0+width2,y0+y1); moveto(x0+width2,y0+y3); lineto(x0+width1,y0+y2);
moveto(x0-width2,y0+y3);/*moveto left bottom side*/ lineto(x0-width2,y0+y1); moveto(x0-width2,y0+y3); lineto(x0-width1,y0+y2);
moveto(x0,y0+y4); /*moveto the bottomest*/ lineto(x0+width1,y0+y2); moveto(x0,y0+y4); lineto(x0-width1,y0+y2);
setfillstyle(2,LIGHTRED); /*fill the plan with a style */ floodfill(x0,y0,LIGHTRED);
size=imagesize(x0-width2-1,y0-height-3*width1, x0+width2+1,y0+y4); buf=malloc(size); if(!buf){ printf("No enough memory!"); exit(0); } getimage(x0-width2,y0-height-3*width1,x0+width2,y0+y4,buf);
}
3 时间分配: 程序编写,录入 5天 程序调试 2天 设计说明书编写 2天 答辩 1天 三. 所需工具(仪器),设备,资料 计算机,打印机,软盘 四. 指导老师:
五. 实训地点: 机房,设计室
六.实习心得 计算机图形学是20世纪60年代以后,随着计算机技术(包括计算机硬件技术和软件技术)的发展和完善而形成的一门新兴学科。至今,计算机图形学已在建筑,机械,电子,造船,航空,汽车,轻工,广告,艺术等领域得到了广泛的应用。可以说,它几乎影响了所有涉及领域,冲击和改变着传统的设计模式。 一打开计算机,人们首先接触到的就是计算机图形学的内容,因为计算机的用户界面已广泛使用了计算机图形技术。事实上,计算机图形技术已深入到各个领域。 计算机图形的生成一般包括两种方法:程序绘图和交互绘图。所谓程序绘图,就是先用计算机语言(例如C语言)编好绘图程序,然后运行该程序并绘出图形。而交互绘图则是应用交互式图形软件,通过交互命令(键盘命令,菜单命令等)由计算机生成图形。程序绘图是交互式绘图的基础。本次实习训练结合了一些典型的例子,了解图形程序的设计和编程方法,所举例的程序均是用Turbo C 2.0编写并通过验证的。 “计算机图形学”是一门实践性很强的课程,本次实习了“计算机图形学”的多项知识,详细练习了二维线画图元的生成(包括二维直线、圆、椭圆、抛物线的生成)、二维填充图元的生成(图形的填充、字符的输出)、本次实习使我加强了本课程理论与实践的了解,是培养我的独立工作能力的重要环节,是一次较全面的设计训练。锻炼了我的实践和动手能力,为我以后的专业课成学习及新兴科学技术的运用打下了坚实基础。更为我以后的就业打下了坚实的良好基础,使我对未来充满了信心。
|
