⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 paint.cpp

📁 用Visual C++实现的绘制函数图像的程序。给定任意函数表达式
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// Paint.cpp : implementation file
//
#include "stdafx.h"
#include "MyPaint.h"
#include "Paint.h"
#include "MyPaintDoc.h"
#include "MyPaintView.h"
#include "MainFrm.h"
#include "math.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define PI 3.1415926
#define E 2.7182818
#define M 50
BYTE error,flag=1,line_count=0;
BOOL outrange=0,notice=0;
short xs=0,ys=0;

MY_LINE *head=NULL,*p2=NULL,*p1=NULL;
MY_LINE *temp;//修改用	
extern char select_line;
/////////////////////////////////////////////////////////////////////////////
// CPaint dialog
CPaint::CPaint(CWnd* pParent /*=NULL*/)
	:CDialog(CPaint::IDD, pParent)
{
    texnew=RGB(63,112,248);
    //{{AFX_DATA_INIT(CPaint)
	m_expres = _T("");
	m_a = -15.0;
	m_b = 15.0;
	m_xexpres = _T("");
	m_yexpres = _T("");
	m_pexpres = _T("");
	m_line_weight = 1;
	m_zexpres = _T("");
	//}}AFX_DATA_INIT
}
void CPaint::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CPaint)
	DDX_Control(pDX, IDC_TAB, m_choices);
	DDX_Control(pDX, IDC_COMBO1, m_pattern);
	DDX_Text(pDX, IDC_EXPRES, m_expres);
	DDX_Text(pDX, IDC_LIMIT_A, m_a);
	DDV_MinMaxDouble(pDX, m_a, -15., 15.);
	DDX_Text(pDX, IDC_LIMIT_B, m_b);
	DDV_MinMaxDouble(pDX, m_b, -15., 15.);
	DDX_Text(pDX, IDC_X_EXPRES, m_xexpres);
	DDX_Text(pDX, IDC_Y_EXPRES, m_yexpres);
	DDX_Text(pDX, IDC_EXPRES2, m_pexpres);
	DDX_Text(pDX, IDC_LINE, m_line_weight);
	DDV_MinMaxByte(pDX, m_line_weight, 1, 10);
	DDX_Text(pDX, IDC_Z_EXPRES, m_zexpres);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CPaint, CDialog)
	//{{AFX_MSG_MAP(CPaint)
	ON_WM_PAINT()
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	ON_BN_CLICKED(ID_PAINT_OK, OnPaintOk)
	ON_BN_CLICKED(ID_PAINT_HIDE, OnPaintHide)
	ON_BN_CLICKED(IDC_EXIT, OnExit)
	ON_EN_CHANGE(IDC_EXPRES, OnChangeExpres)
	ON_WM_LBUTTONDOWN()
	ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
	ON_NOTIFY(TCN_SELCHANGE, IDC_TAB, OnSelchangeTab)
	ON_BN_CLICKED(ID_PAINT_OK2, OnPaintOk2)
	ON_EN_CHANGE(IDC_X_EXPRES, OnChangeXExpres)
	ON_EN_CHANGE(IDC_Y_EXPRES, OnChangeYExpres)
	ON_EN_CHANGE(IDC_EXPRES2, OnChangeExpres2)
	ON_BN_CLICKED(ID_PAINT_OK3, OnPaintOk3)
	ON_BN_CLICKED(ID_MODIFY, OnModify)
	ON_EN_CHANGE(IDC_Z_EXPRES, OnChangeZExpres)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//自制随机数发生器,产生0~200的整数,但产生越小的数的概率越大
COLORREF myrand(void)
{
	CTime time=CTime::GetCurrentTime();
	BYTE i=time.GetSecond()%10+1;
	return RGB(rand()*i/1638,rand()*i/1638,rand()*i/1638);
}


////////用麦克老林算幂
double mi(double x,double n)
{
	BYTE i;
	double sum=1,part=1,xpart=1,npart=1,numpart=1;
	if(n>=0)
	{
		if((x>=0||fabs(n-(long)n)<1e-6))
		{		 
			for(i=1;fabs(part)>=1e-6;i++)
			{
				xpart=xpart*(x-1);
				npart=npart*n;
				n-=1;
				numpart=numpart*i;
				part=npart*xpart/numpart;
				sum=sum+part;
			}
			return sum;
		}
		else
			return 0;
		
	}
	else
	{
		n=-n;
		if(x>=0||fabs(n-(long)n)<1e-6)
		{
			for(i=1;fabs(part)>=1e-1;i++)
			{
				xpart=xpart*(x-1);
				npart=npart*n;
				n-=1;
				numpart=numpart*i;
				part=npart*xpart/numpart;
				sum=sum+part;
			}
			return 1/sum;
		}
		else
			return 0;
	}
}
//powechge()的设计思想是,首先将表达式中的每一个数据的正负性保存到一个初始时全为1的数组a[]里,比如“--5*-22-6”,则相应a[0]=1,a[1]=-1,a[2]=-1;
//再将一个字符串形式的四则运算表达式进行分离,把字符串中的数字以及字符'x'分离组成一个二维字符数组data[][],
//把+-*/运算符组成一个一维字符数组operat[],其中-变+,因为前面已经保存了正负性;比如字符串是“5*x+61-123”,则data[0]="5",data[1]="x",data[2]="61",data[3]="123";
//operat[0]='*',operat[1]='+'operat[2]='-'.然后把data转化成数字型数组num[],即,num[0]=5,num[1]=x,num[2]=61,num[3]=123;
//然后再在operat[]里寻找*和/号,并把相应的2个num[]进行运算,把运算结果存放在后面一个num[]中,接着再找+号,找到一个+号后,
//再往这个+号后面寻找下一个+或-或直到结束,把第一个+号前面的num和第二个+或-或结束前面的num相加,结果放在后一个num......
//做完之后,num[]里最后一个元素就是这个表达式的值了!
char part[M]={0},expres[M]={0};
double powerchge(char *part,double x,char flag='x')
	{	    
	    char data[20][18],operat[20];
		BYTE j,m,swich=0,n;
		BYTE aa=0,open=0;
		short a[20];		
		for(j=0;j<20;a[j++]=1);
		for(j=0;part[j]!='\0';j++)//把part里每个数的正负性保存下来,顺便检查语法错误
		{
			if(part[j]==' ')
				continue;
			if(part[j]=='-')
			{
				a[aa]=-a[aa];
				open=0;
			}
			else
			{
				if(open==0||(part[j]=='+'||part[j]=='/'||part[j]=='*')&&part[j+1]!='-') 
					aa++;
				open=1;
			}
			if((part[j]<48||part[j]>57)&&part[j]!=flag&&part[j]!='.'&&part[j]!='e'&&part[j]!='p'&&part[j]!='+'&&part[j]!='-'&&part[j]!='*'&&part[j]!='/')
			{
				error=5;
				return 0;
			}
			else
			if((part[j]==flag||part[j]=='e'||part[j]=='p')&&part[j+1]!='+'&&part[j+1]!='-'&&part[j+1]!='*'&&part[j+1]!='/'&&part[j+1]!=0&&part[j+1]!=' ')
			{
				error=4;
				return 0;
			}
			else
			if((part[j]==flag||part[j]=='e'||part[j]=='p')&&part[j-1]!='+'&&part[j-1]!='-'&&part[j-1]!='*'&&part[j-1]!='/'&&j!=0&&part[j-1]!=' ')
			{
				error=4;
				return 0;
			}
			else
			if(part[j]=='.'&&(part[j+1]<48||part[j+1]>57))
			{
				error=4;
				return 0;
			}
		}
		for(j=0,m=0,n=0;part[j]!='\0';j++,m++)
		{
			if(part[j]==' ')
			{
				m=-1;
				continue;
			}
			if((part[j]<48||part[j]>57)&&part[j]!=flag&&part[j]!='.'&&part[j]!='e'&&part[j]!='p')
			{
				if(swich==1)
				{
					if(part[j]=='-') 
						part[j]='+';				
					if(part[j+1]=='*'||part[j+1]=='/')
					{
						error=1;
					}
					operat[n]=part[j];
					n++;
					swich=0;
				}//存放运算符,如果是-则变+;顺便检查错误
				m=-1;				
			}
			else
			{
				if(m==14)
				{
					outrange=1;
					return 0;
				}
				data[n][m]=part[j];
				error=0;
				swich=1;				
			}
		}//--------------------------------把一维数组PART分离成数字字符数组DATA,和运算符字符数组OPERAT;并把字符X取代为X的数值;
		CString datanum[20];
		double num[20];
		for(BYTE i=0;i<n+1;i++)
		{
			if(data[i][0]==flag) num[i]=a[i]*x;//把数字与它前面的符号相乘
			else
			if(data[i][0]=='e') num[i]=a[i]*E;
			else
			if(data[i][0]=='p') num[i]=a[i]*PI;
			else
			{		
				datanum[i]=data[i];
				num[i]=a[i]*atof(datanum[i]);//把数字与它前面的符号相乘
			}		
		}		//-------------------------------把DATA转化成double型数组num,使用中间数组datanum
		for(i=0;i<n;i++)
		{
			if(operat[i]=='*')
				num[i+1]=num[i]*num[i+1];
			else
			if(operat[i]=='/')
			{
				if(fabs(num[i]-0)<1e-6&&fabs(num[i+1]-0)<1e-6)
					num[i+1]=1;
				else
					num[i+1]=num[i]/num[i+1];
			}
		}
		for(i=0;i<n;i++)
		{
			if(operat[i]=='+')
			{
				for(j=i+1;operat[j]!='+'&&operat[j]!='-'&&j!=n;j++);
				num[j]=num[i]+num[j];
	       	}
			//由于part里已经没有‘-’号运算符,所以只算+法就行了
		}
		return num[n];
	
}

			
////////////////////////////////////////////////////////////////////////////////
//superchge的思想是,在一个含有多重括号的表达式里,先找括号‘)’,再找与它最近的‘(’,
//于是( )里面一定是一个简单的四则运算表达式,将这个式子送进powerchge()里,返回一个表达式的数值,
//再将这个数值转成字符串数组,然后将这个字符串数组和( )外面的字符串再重新组合成一个新的字符串形式的表达式.
//然后继续找下一个")",如此循环,等到把")"找完之时,便是一个全新的不含()的简单的四则运算表达式诞生之时,
//哈哈(依然是字符串形式),然后把它再送进powerchge()里,返回得到的数值,这个数值,边是最终的答案了.
double superchge(char *expres,double xl,char flag='x')
{
	char expresbak[M]={0},partsumch[M]={0};
	CString partsumcs;
	BYTE length=0,i;
	short j;
	double result;
	BYTE k=0;
	strcpy(expresbak,expres);  //把expres备分到expresbak[]里
	for(i=0,j=0;expres[i]!='\0';i++)
	{
		if(expres[i]==')')
		{
			for(j=i-1;j>=0;j--)
			{
				if(expres[j]=='(')
				{								
					for(BYTE m=0,n=j+1;n<i;part[m++]=expres[n++]);//构建最底层的( )内的PART--------				
					//-----------------------判断'('左边是不是有函数符号,并进行相应的处理                  
					if((expres[j-1]<97||expres[j-1]>122)&&expres[j-1]!='^')//----------------------------------如果没有函数字符时的处理
					{
						partsumcs.Format("%f",powerchge(part,xl,flag));
						length=0;
					}
					else
					if(expres[j-1]=='^')
					{
						if(expres[j-2]==flag)
						{
							partsumcs.Format("%f",mi(xl,powerchge(part,xl,flag)) );
							length=2;
						}
						else
						if(expres[j-2]=='e')
						{
							partsumcs.Format("%f",mi(E,powerchge(part,xl,flag)) );
							length=2;
						}
						else
						if(expres[j-2]>='0'&&expres[j-2]<='9'||expres[j-2]=='.')
						{
							char temp[15];
							CString tempchge;
							for(k=0;k<10;temp[k++]=0);
							for(k=j-2;expres[k]>='0'&&expres[k]<='9'||expres[k]=='.';k--);
							for(k+=1;k<j-1&&length<15;temp[length++]=expres[k++]);
							tempchge=temp;
							partsumcs.Format("%f",mi(atof(tempchge),powerchge(part,xl,flag)) );
							length+=1;
						}
						else						
						{
							error=3;					
							return 0;
						}
					}
					else
					if (expres[j-2]=='l'&&expres[j-1]=='n')  //-------------判断'('左边是不是有函数符号,并进行相应的处理
					{
						partsumcs.Format("%f",log(powerchge(part,xl,flag)));
						length=2;
					}
					else
					if (expres[j-4]!='a'&&expres[j-3]=='c'&&expres[j-2]=='o'&&expres[j-1]=='s')//-------------判断'('左边是不是有函数符号,并进行相应的处理
					{
						partsumcs.Format("%f",cos(powerchge(part,xl,flag)));
						length=3;
					}
					else
                    if (expres[j-4]!='a'&&expres[j-3]=='s'&&expres[j-2]=='i'&&expres[j-1]=='n')//-------------判断'('左边是不是有函数符号,并进行相应的处理								{
					{
						partsumcs.Format("%f",sin(powerchge(part,xl,flag)));
						length=3;
					}
					else
                    if (expres[j-4]!='a'&&expres[j-3]=='t'&&expres[j-2]=='a'&&expres[j-1]=='n')//-------------判断'('左边是不是有函数符号,并进行相应的处理
					{
						partsumcs.Format("%f",tan(powerchge(part,xl,flag)));
						length=3;
					}
					else
					if (expres[j-4]!='a'&&expres[j-3]=='c'&&expres[j-2]=='t'&&expres[j-1]=='g')//-------------判断'('左边是不是有函数符号,并进行相应的处理
					{
						partsumcs.Format("%f",1/tan(powerchge(part,xl,flag)));
						length=3;
					}
					else
                    if (expres[j-4]=='f'&&expres[j-3]=='a'&&expres[j-2]=='b'&&expres[j-1]=='s')//-------------判断'('左边是不是有函数符号,并进行相应的处理							{
					{
						partsumcs.Format("%f",fabs(powerchge(part,xl,flag)));
						length=4;
					}
					else
					if (expres[j-4]=='s'&&expres[j-3]=='q'&&expres[j-2]=='r'&&expres[j-1]=='t')//-------------判断'('左边是不是有函数符号,并进行相应的处理							{
					{
						partsumcs.Format("%f",sqrt(powerchge(part,xl,flag)));
						length=4;
					}
					else	
					if (expres[j-4]=='a'&&expres[j-3]=='s'&&expres[j-2]=='i'&&expres[j-1]=='n')//-------------判断'('左边是不是有函数符号,并进行相应的处理
					{
						partsumcs.Format("%f",asin(powerchge(part,xl,flag)));
						length=4;
					}
					else
                    if (expres[j-4]=='a'&&expres[j-3]=='c'&&expres[j-2]=='o'&&expres[j-1]=='s')//-------------判断'('左边是不是有函数符号,并进行相应的处理
					{
						partsumcs.Format("%f",acos(powerchge(part,xl,flag)));
						length=4;
					}
					else
                    if (expres[j-4]=='a'&&expres[j-3]=='t'&&expres[j-2]=='a'&&expres[j-1]=='n')//-------------判断'('左边是不是有函数符号,并进行相应的处理
					{
						partsumcs.Format("%f",atan(powerchge(part,xl,flag)));
						length=4;
					}
				    else
                    if (expres[j-4]=='a'&&expres[j-3]=='c'&&expres[j-2]=='t'&&expres[j-1]=='g')//-------------判断'('左边是不是有函数符号,并进行相应的处理
					{
						partsumcs.Format("%f",PI/2-atan(powerchge(part,xl,flag)));
						length=4;
					}
					else
					if (expres[j-4]=='s'&&expres[j-3]=='i'&&expres[j-2]=='n'&&expres[j-1]=='h')//-------------判断'('左边是不是有函数符号,并进行相应的处理
					{
						partsumcs.Format("%f",sinh(powerchge(part,xl,flag)));
						length=4;
					}
					else
					if (expres[j-4]=='c'&&expres[j-3]=='o'&&expres[j-2]=='s'&&expres[j-1]=='h')//-------------判断'('左边是不是有函数符号,并进行相应的处理
					{
						partsumcs.Format("%f",cosh(powerchge(part,xl,flag)));
						length=4;
					}
					else
					if (expres[j-4]=='t'&&expres[j-3]=='a'&&expres[j-2]=='n'&&expres[j-1]=='h')//-------------判断'('左边是不是有函数符号,并进行相应的处理
					{
						partsumcs.Format("%f",tanh(powerchge(part,xl,flag)));
						length=4;
					}
					else
					{
						error=2;
						return 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -