大作业二—绘图板

翁恺大作业二 画函数图像

之前写的计算器没用到,自己有重写了一个,这次用了好多栈,感觉最失败的地方是没有事先构思好框架,一有bug就补一个判断,又产生新的bug,唉。

代码:(中间注释的一大片是debug时写的,后来bug越弄越多,受不了了,就停工了。

//2019.4.17 16:00--2019.4.18 0:30
//2019.4.20 7:10--14:20
//2019.4.21 17:00--21:00 发现乘法的bug,debug无果,哭 
//3180105524 黄隆钤 
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#include"acllib.h" 
#include<ctype.h>
void read();
int isop(char ch); 
void paint(char *fname);
char fname[1000];
int Setup()
{
	initConsole();
    initWindow("paintfx",-1,-1,800,600);
	read(fname);
	paint(fname);
 	return 0;
}
int isop(char ch)
{
	return ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='^';
}
void read(char *fname)
{ 
	char ch;
	int k=0,i,pl=0,pr=0;
	ch=getchar();
	while(ch!='\n')
	{
		if(ch==' ')
		{
			ch=getchar(); 
			continue;
		}
		fname[k++]=ch;
		ch=getchar();
	}
	for(i=0;i<strlen(fname);i++)
	{
		if(fname[i]=='(')pl++;
		if(fname[i]==')')pr++;
	}
	if(pr!=pl)
	{
		printf("input error!");
		memset(fname,'\0',sizeof(fname));
		return;
	}
	return;
}
double func(char*d,double x)
{
	if(strcmp(d,"nis")==0)return sin(x);
    else if(strcmp(d,"soc")==0)return cos(x);
    else if(strcmp(d,"nat")==0)return tan(x);
    else if(strcmp(d,"toc")==0)return 1/tan(x);
    else if(strcmp(d,"csc")==0)return 1/sin(x);
    else if(strcmp(d,"ces")==0)return 1/cos(x);
    else if(strcmp(d,"natcra")==0)return atan(x);
    else if(strcmp(d,"soccra")==0)return acos(x);	
    else if(strcmp(d,"niscra")==0)return asin(x);
    else if(strcmp(d,"e")==0)return exp(x);
	else if(strcmp(d,"hnis")==0)return sinh(x);
	else if(strcmp(d,"hsoc")==0)return cosh(x);
	else if(strcmp(d,"hnat")==0)return tanh(x);
	else if(strcmp(d,"nl")==0)return log(x);
	else if(strcmp(d,"gl")==0)return log10(x);
	else if(strcmp(d,"trqs")==0)return sqrt(x);
	else if(strcmp(d,"roolf")==0)return floor(x);
	else if(strcmp(d,"sba")==0)return abs(x);
}
int prior(char a){
	if(a=='+'||a=='-')return 1;
	if(a=='*'||a=='/')return 2;
	if(a=='^')return 3;
}
double cal(double x,double y,char ch)
{
	if(ch=='+')return x+y;
	if(ch=='-')return x-y;
	if(ch=='*')return x*y;
	if(ch=='/')return x/y; 
	if(ch=='^')return pow(x,y);
}
/*double f(double x)
{
	char numstack[1000]={'\0'};//系数栈 放x前面的系数 利用这个省去“* ” 
	numstack[0]='1';
	int numtop=0;
	double dstack[1000]={0};//结果栈 存放一个运算块的运算结果  
	int dtop=0;
	int i=0,l=strlen(fname);
	//dstack[++dtop]=1;//结果栈初始化为1 
	char opstack[1000]={'\0'};//符号栈 存放操作符 
	int optop=0;
	int flag=0,aflag=0;
	char fstack[1000]={'\0'};//函数栈 存放函数名 
	fstack[0]=' ';
	int ftop=0;
	char fun[1000]={'\0'};//用来调用函数栈里的函数 
	int fk=0;
	int plusflag=0;//很重要的一个标记 区分sin(x)+cos(x)和sin(2x+1)中“+ ”号的不同 
//	int lpara=0,rpara=0;
	//以上是初始化 
	while(i<l)
	{
		if(isalpha(fname[i]))//如果是字母 
		{
	 	    if(fname[i]=='x')//字母为x 
			 {
			 	dstack[++dtop]=1;
			 	dstack[dtop]*=x;
			 	i++;
			 }
  			else
			  {
 				while(isalpha(fname[i])&&fname[i]!='x')
				{
					if(fname[i]=='(')break;
					else if(isalpha(fname[i]))fstack[++ftop]=fname[i++];
				}
				fstack[++ftop]=' ';
			  }
		}
		else if(fname[i]=='(')
		{
			//lpara++;
			/*if(i>=2&&!isalpha(fname[i-2])&&!isalpha(fname[i-1]))
			{
				dstack[dtop]*=atof(numstack);
				memset(numstack,'\0',sizeof(numstack));
				numstack[0]='1';
				numtop=0;
				dstack[++dtop]=1;
			}*/
			/*i++;
		}
		else if(isdigit(fname[i]))//如果是数字 
		{
			while(isdigit(fname[i])||fname[i]=='.')numstack[numtop++]=fname[i++];
			dstack[++dtop]=atof(numstack);
			memset(numstack,'\0',sizeof(numstack));
					numstack[0]='1';
					numtop=0;
			if(fname[i]=='x')	
			{
				if(i+1<l&&fname[i+1]!='^')
				{
					dstack[dtop]*=x;
					memset(numstack,'\0',sizeof(numstack));
					numstack[0]='1';
					numtop=0;
				}	
			 	i++;
			}
		} 
		else if(isop(fname[i]))//如果是操作符 
		{
			if(fname[i]=='+'||fname[i]=='-')//如果是加号或者减号 
			{
				if(fname[i-1]==')')plusflag=1;//如果加减号前面是右括号 则不能直接对结果栈进行运算 
			}
			if(fname[i]=='^')
			{
				/*if(numtop&&fname[i-1]!='x')//如果系数栈里有东西 则是指数函数类型 更新栈顶 
			 	{
	 			    dstack[dtop]*=atof(numstack);
					memset(numstack,'\0',sizeof(numstack));
					numstack[0]='1';
					numtop=0;
		 		}
			    if((!isdigit(fname[i+1])&&fname[i+1]!='x')||i+1==l)
				{
		    		printf("输入错误!");
		    		system("pause");
					exit(0); 
			    }
            	if(fname[i+1]=='x')//指数函数 
				{
					dstack[dtop]=pow(dstack[dtop],x);
					i++;
				}
			//	else
			    if(isdigit(fname[i+1]))//幂函数 
				{
					dstack[dtop]=pow(dstack[dtop],fname[i+1]-'0');
					i++;
				}
				else opstack[++optop]=fname[i];

			}
			else if(optop==0||prior(fname[i])>prior(opstack[optop]))
		    {
	 		    opstack[++optop]=fname[i];
	 		    dstack[++dtop]=1;
			}
			else if(optop&&prior(fname[i])<=prior(opstack[optop]))//运算
			{
				int j=1;
				//if(lpara==rpara)
				//{
						while(optop>0)
					{	
						dstack[dtop]=cal(dstack[dtop-j],dstack[dtop],opstack[optop--]);
						j++;
					}
			//	}
				
				opstack[++optop]=fname[i];
				dstack[++dtop]=1;
			}
			i++;
	    }
	    
		else if(fname[i]==')')
		 {		 
   		    //rpara++;
   		   /* if(numtop)
		 	{
 			    dstack[dtop]*=atof(numstack);
				memset(numstack,'\0',sizeof(numstack));
				numstack[0]='1';
				numtop=0;
	 		}
	 	    if(optop>0&&(opstack[optop]=='+'||opstack[optop]=='-')&&plusflag==0)
			{
				//dstack[dtop]=cal(dstack[dtop-1],dstack[dtop],opstack[optop--]);
				int j=1;
			    while(optop>0)
					{	
						dstack[dtop]=cal(dstack[dtop-j],dstack[dtop],opstack[optop--]);
						j++;
					}
				
			}
			else if(optop>0&&plusflag)plusflag=0;
	    	
			if(ftop>0)ftop--;
    		
			i++;
			if(ftop==0)fstack[ftop]=' ';
			else
			{
				while(fstack[ftop]!=' ')
	    		{
				    fun[fk++]=fstack[ftop];
				    fstack[ftop]='\0';
				    ftop--;
				}
				dstack[dtop]=func(fun,dstack[dtop]);
				memset(fun,'\0',sizeof(fun));
				fk=0;
			}//依次对栈顶作用函数栈中的各函数 
					    		    
		}
	}
	if(optop>0)
	{
	//	if(numtop)dstack[dtop]*=atof(numstack);
		dstack[dtop]=cal(dstack[dtop-1],dstack[dtop],opstack[optop--]);
	}
	return dstack[dtop];
}*/
double f(double x)
{
	char numstack[1000]={'\0'};//系数栈 放x前面的系数 利用这个省去“* ”
	numstack[0]='1';
	int numtop=0;
	double dstack[1000]={0};//结果栈 存放一个运算块的运算结果
	int dtop=0;
	int i=0,l=strlen(fname);
	dstack[++dtop]=1;//结果栈初始化为1
	char opstack[1000]={'\0'};//符号栈 存放操作符
	int optop=0;
	int flag=0,aflag=0;
	char fstack[1000]={'\0'};//函数栈 存放函数名
	fstack[0]=' ';
	int ftop=0;
	char fun[1000]={'\0'};//用来调用函数栈里的函数
	int fk=0;
	int plusflag=0;//很重要的一个标记 区分sin(x)+cos(x)和sin(2x+1)中的加号
	//以上是初始化
	while(i<l)
	{
		if(isalpha(fname[i]))//如果是字母
		{
	 	    if(fname[i]=='x')//字母为x
			 {
			 	dstack[dtop]*=x;
			 	i++;
			 }
  		else {
 			while((isalpha(fname[i])&&fname[i]!='x')||fname[i]=='(')
			{
				if(fname[i]=='(')
				{
					fstack[++ftop]=' ';
					i++;
				}
				else if(isalpha(fname[i]))fstack[++ftop]=fname[i++];
			}
		   }
		}
		else if(isdigit(fname[i]))//如果是数字
		while(isdigit(fname[i])||fname[i]=='.')numstack[numtop++]=fname[i++];	
		else if(isop(fname[i]))//如果是操作符
		{
			if(fname[i]=='+'||fname[i]=='-')//如果是加号或者减号
			{
			    dstack[dtop]*=atof(numstack);
			    memset(numstack,'\0',sizeof(numstack));
			    numstack[0]='1';
			    numtop=0;
			 if(fname[i-1]==')')plusflag=1;//如果加减号前面有右括号 标记 
			}
			if(fname[i]=='^')
			{
				if(numtop&&fname[i-1]!='x')//前面如果是x则不操作,此时为幂函数
			 	{
	 			    dstack[dtop]*=atof(numstack);
					memset(numstack,'\0',sizeof(numstack));
					numstack[0]='1';
					numtop=0;
		 		}
			    if((!isdigit(fname[i+1])&&fname[i+1]!='x')||i+1==l)
				{
		    		printf("输入错误!");
		    		system("pause");
					exit(0);
			    }
                            if(fname[i+1]=='x')//指数函数
				{
					dstack[dtop]=pow(dstack[dtop],x);
					i++;
				}
				else if(isdigit(fname[i+1]))//幂函数
				{
					dstack[dtop]=pow(dstack[dtop],fname[i+1]-'0');
					i++;
				}

			}
			else if(optop==0||prior(fname[i])>prior(opstack[optop]))
		        {
	 		    opstack[++optop]=fname[i];
	 		    dstack[++dtop]=1;
			}
			else if(optop&&prior(fname[i])<=prior(opstack[optop]))//运算
			{
			 int j=1;
		    while(optop>0){	
		    dstack[dtop]=cal(dstack[dtop-j],dstack[dtop],opstack[optop--]);
		    j++;
			}
				opstack[++optop]=fname[i];
				dstack[++dtop]=1;
			}
			i++;
	    }
	
		else if(fname[i]==')')
		{		
	 	  if(optop>0&&plusflag==0)
		  {
		    dstack[dtop]=cal(dstack[dtop-1],dstack[dtop],opstack[optop--]);
		  }
			else if(optop>0&&plusflag)plusflag=0;
	    	        ftop--;
    		        i++;
			if(ftop==0)fstack[ftop]=' ';
			else
			{
				while(fstack[ftop]!=' ')
	    	    {
				    fun[fk++]=fstack[ftop];
				    fstack[ftop]='\0';
				    ftop--;
				}
				dstack[dtop]=func(fun,dstack[dtop]);
				memset(fun,'\0',sizeof(fun));
				fk=0;
			}//依次对栈顶作用函数栈中的各函数
			if(numtop)
		 	{
 			    dstack[dtop]*=atof(numstack);
			    memset(numstack,'\0',sizeof(numstack));
			    numstack[0]='1';
			    numtop=0;
	 		}		    		
		}
	}
	if(optop>0)
	{
		if(numtop)dstack[dtop]*=atof(numstack);
		dstack[dtop]=cal(dstack[dtop-1],dstack[dtop],opstack[optop--]);
	}
	return dstack[dtop];
}

void paintpoint(int w,int h)
{
	
	double maxx=-100000.0,min=100000;
    double x;
   	for(x=-10;x<10;x+=0.5)
	{
		if(f(x)>maxx)maxx=fabs(f(x));
	}
	double k=3*h/(8*maxx);//换算系数
	beginPaint();
	for(x=-9.999;x<=10;x+=0.0001)
	{
		double nx=x*w/20+w/2,ny=-f(x)*k+h/2;
		putPixel(nx,ny,BLUE);//注意纵坐标 加个负号 
	}
	char mmax[100],mmin[100];
	sprintf(mmax,"%.1f",maxx);
	int l=strlen(mmax)-1;
	double ls=(l-2)*7;
	paintText(w/2-22-ls,h/2-maxx*k-3,mmax); 
	endPaint();
}
void paintcoordinate(w,h)
{
	beginPaint();
	paintText(w/2-15,h/2+15,"0");//注意最后一个参数是string 
	line(0,h/2,w,h/2);
	line(w/2,0,w/2,h);
	line(w/2,0,w/2-15,17);
	line(w/2,0,w/2+15,17);
	line(w,h/2,w-17,h/2-15);
	line(w,h/2,w-17,h/2+15);
	endPaint();
}
void paintfname(int w,int h,char *fname)
{
	setTextFont("宋体");
	setTextBkColor(EMPTY);//透明 
	setTextColor(BLACK);
	setTextSize(20);
	beginPaint();
	char p[1000]={'\0'};
	char p1[100]={'\0'},p2[100]={'\0'},
	p3[100]={'\0'},p4[100]={'\0'};
	p[0]='y';
	p[1]='=';
	strcat(p,fname);
	int ll=strlen(p);
	//为了把函数名控制在y轴左边的一定范围
	//进行了一个小计算,调整函数名的位置 
    for(int j=0;j<ll;j++)
	{
		if(j<28)p1[j]=p[j];
		else if(j<56)p2[j-28]=p[j];
		else if(j<84)p3[j-56]=p[j];
		else if(j<112)p4[j-84]=p[j];
		paintText(35,h*1/6-30,p1);
		paintText(35,h*1/6,p2);
		paintText(35,h*1/6+30,p3);
		paintText(35,h*1/6+60,p4);
	}
	endPaint();
}
void paint(char* fname)
{
	int w=getWidth(),h=getHeight();
	setTextBkColor(EMPTY);
	paintpoint(w,h);
	paintcoordinate(w,h);
	paintfname(w,h,fname);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值