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; 
}