www.pudn.com > DRAWFS.rar > DRAWFS.C
/* DrawFS.C -- Drawing surface of function */ #include#include #include #include #include #define Xmax 640 #define Ymax 480 #define zs 10.0 #define lcol 11 #define fcol 12 #define bcol 3 #define ecol 10 typedef struct{int x,y;} POINT; typedef struct{double x,y,z;} VECTOR; VECTOR e; POINT s(double x,double y,double z); double f(double x,double y,int no); int ne(double x,double y,int no); double s1,s2,c1,c2,rho=35; void main(int argc,char *argv[]) { double theta=45,phi=60,dt=5,dp=5,dr=1,times=4; double x,y,z,dx,dy; /*'frame' is a bool variable to choose if you want to display a frame,] you can press 'F' to change the condition. 'no' is the funtion's number ,you can press '1' to '7' to choose to display different funtion */ int n=50,frame=1,si,sj,sk,i,j,key=1,no=1; POINT p[4],pf[8],ps,p0,*pa; int gd=VGA,gm=VGAHI; char buf[40]; enum {up=0x48,down=0x50,left=0x4b,right=0x4d,add=0x2b,sub=0x2d,Esc=0x1b, ctrl_up=0x8d,ctrl_down=0x91,ctrl_left=0x73,ctrl_right=0x74, ctrl_add=0x90,ctrl_sub=0x8e,addl=0x3d,ctrl_subl=0x1f}; /* read degree from command line */ if(argc>1) { theta=atof(argv[1]); if(argc>2) phi=atof(argv[2]); } /* allocate memory */ pa=(POINT *)calloc(n,sizeof(POINT)); if(pa==NULL) { printf("\nNo enough memory!"); return; } /* initial graphics */ registerbgidriver(EGAVGA_driver); initgraph(&gd,&gm,""); setbkcolor(0); setcolor(ecol); /* main circle -- change degree or rho and draw */ while(key!=0x1b) /* Esc: exit */ { /* calculate parameters ,M_PI for pi*/ s1=sin(theta*M_PI/180); c1=cos(theta*M_PI/180); s2=sin(phi*M_PI/180); c2=cos(phi*M_PI/180); e.x=c1*s2; e.y=s1*s2; e.z=c2; if(c1<0) si=-1; else si=1; if(s1<0) sj=-1; else sj=1; if(c2<0) sk=-1; else sk=1; dx=si*(2.0/n); dy=sj*(2.0/n); cleardevice(); /* clear screen */ /* write information to screen */ sprintf(buf,"theta=%g",theta); //output to a string outtextxy(10,10,buf); //display a string at a specified position at graphics mode sprintf(buf,"phi=%g",phi); outtextxy(10,20,buf); sprintf(buf,"zs=%g",zs); outtextxy(10,452,buf); sprintf(buf,"rho=%g",rho); outtextxy(10,462,buf); outtextxy(450,10,"(ctrl+) arrow to rotate"); outtextxy(450,20,"(ctrl+) + or - to zoom"); outtextxy(450,30," to exit"); /* calculate coordinates of frame point */ pf[0]=s(-si,-sj,-sk); pf[1]=s(si,-sj,-sk); pf[2]=s(-si,sj,-sk); pf[3]=s(si,sj,-sk); pf[4]=s(-si,-sj,sk); pf[5]=s(si,-sj,sk); pf[6]=s(-si,sj,sk); pf[7]=s(si,sj,sk); /* draw frame -- back */ if(frame) { setcolor(lcol); line(pf[0].x,pf[0].y,pf[1].x,pf[1].y); line(pf[0].x,pf[0].y,pf[2].x,pf[2].y); line(pf[0].x,pf[0].y,pf[4].x,pf[4].y); line(pf[1].x,pf[1].y,pf[5].x,pf[5].y); line(pf[2].x,pf[2].y,pf[6].x,pf[6].y); line(pf[4].x,pf[4].y,pf[5].x,pf[5].y); line(pf[4].x,pf[4].y,pf[6].x,pf[6].y); setcolor(ecol); } /* draw surface */ /*for(i=0;i<=n;i++) { for(j=0;j<=n;j++) { x=-si+i*dx; y=-sj+j*dy; z=f(x,y,no); if(z==-100) continue; ps=s(x,y,z); if(i==0) pa[j]=ps; else{ // i>0 if(j==0) {p0=pa[0]; pa[0]=ps; }else{ // j>0 p[0]=p0; p[1]=pa[j-1]; p[2]=ps; p[3]=pa[j]; if(ne(x,y,no)) setfillstyle(1,fcol); else setfillstyle(1,bcol); fillpoly(4,(int *)p); p0=pa[j]; pa[j]=ps; } } } }*/ double *yu=(double *)calloc(n,sizeof(double)); for(i=n;i>=0;i--) { for(j=0;j<=n;j++) { x=-si+i*dx; z=-sj+j*dz; y=f(x,z,no); if(z==-100) continue; ps=s(x,y,z); if(i==0) pa[j]=ps; else{ // i>0 if(j==0) {p0=pa[0]; pa[0]=ps; }else{ // j>0 p[0]=p0; p[1]=pa[j-1]; p[2]=ps; p[3]=pa[j]; if(ne(x,y,no)) setfillstyle(1,fcol); else setfillstyle(1,bcol); fillpoly(4,(int *)p); p0=pa[j]; pa[j]=ps; } } } } /* draw frame -- front */ if(frame) { setcolor(lcol); line(pf[1].x,pf[1].y,pf[3].x,pf[3].y); line(pf[2].x,pf[2].y,pf[3].x,pf[3].y); line(pf[3].x,pf[3].y,pf[7].x,pf[7].y); line(pf[5].x,pf[5].y,pf[7].x,pf[7].y); line(pf[6].x,pf[6].y,pf[7].x,pf[7].y); setcolor(ecol); } /* press key to change parameter */ again: key=getch(); if(key==0) key=getch(); switch(key) { case up: phi-=dp; break; case down: phi+=dp; break; case left: theta-=dt; break; case right: theta+=dt; break; case addl: case add: rho+=dr; break; case sub: rho-=dr; break; case ctrl_up: phi-=times*dp; break; case ctrl_down: phi+=times*dp; break; case ctrl_left: theta-=times*dt; break; case ctrl_right: theta+=times*dt; break; case ctrl_add: rho+=times*dr; break; case ctrl_subl: case ctrl_sub: rho-=times*dr; break; case '1': no=1; break; case '2': no=2; break; case '3': no=3; break; case '4': no=4; break; case '5': no=5; break; case '6': no=6; break; case '7': no=7; break; case 'f': case 'F': frame=!frame; break; default : if(key!=Esc) goto again; } if(theta>360) theta-=360; else if(theta<0) theta=360-theta; if(phi>180) { phi=180; putch('\a'); }else if(phi<0) { phi=0; putch('\a'); } } closegraph(); free(pa); } /* function of calculate screen coordinates */ POINT s(double x,double y,double z) { double xe,ye,ze; POINT p; xe=-x*s1+y*c1; ye=-(x*c1+y*s1)*c2+z*s2; ze=-(x*c1+y*s1)*s2-z*c2+rho; p.x=Xmax*(0.5+zs*xe/ze)+0.5; p.y=Ymax*(0.5-zs*ye/ze)+0.5; return p; } /* function of calculate z=f(x,y,no) */ double f(double x,double y,int no) { double t; switch(no) { case 1: return 1.462*cos(4*M_PI*(x*x+y*y))*exp(-4*(x*x+y*y))-0.462; case 2: return sin(M_PI*x)+cos(M_PI*y); case 3: t=x*x+4*y*y; if(t<1) return sqrt(1-t); else return 0; case 4: t=x*x+4*y*y; if(t<1) return -sqrt(1-t); else return 0; case 5: return x*x+y*y-1; case 6: return 0.5*(x*x+3*y*y-2); case 7: return x*x-y*y; } return 0; } /* function of calculate n*e */ int ne(double x,double y,int no) { double fx,fy,t; switch(no) { case 1: t=-1.462*8*exp(-4*(x*x+y*y))*(M_PI*sin(4*M_PI*(x*x+y*y))+cos(4*M_PI*(x*x+y*y))); fx=t*x; fy=t*y; break; case 2: fx=M_PI*cos(M_PI*x); fy=-M_PI*sin(M_PI*y); break; case 3: t=x*x+4*y*y; if(t<1) { t=1/sqrt(1-t); fx=-x/t; fy=-4*y/t; } else fx = fy = 0; break; case 4: t=x*x+4*y*y; if(t<1) { t=1/sqrt(1-t); fx=x/t; fy=4*y/t; } else fx = fy = 0; break; case 5: fx=2*x; fy=2*y; break; case 6: fx=x; fy=4*y; break; case 7: fx=2*x; fy=-2*y; break; } if(-fx*e.x-fy*e.y+e.z>=0) return 1; else return 0; }