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

📄 piddlg.cpp

📁 实现了PID控制的仿真显示
💻 CPP
📖 第 1 页 / 共 2 页
字号:
       if(minX>0)
              minX=0; 
       //如果原点必须在Y轴上,加上下面2行,否则注释掉
       if(minY>0)
              minY=0; 
       //确定图象显示大小
       int width=860;
       int height=300;
	    //确定坐标图四周预留的空白大小
      const int mytop=20;
      const int mybottom=20;
      const int myleft=80;
      const int myright=50;
	  const int topextend=20;
	  
        //确定X,Y轴每单位显示宽度
      double intervalX=(width-myleft-myright)/(maxX-minX);
      double intervalY=(height-mybottom-mytop)/(maxY-minY);
	  //绘制X,Y轴
	   	poldpen1=pDC->SelectObject(&pen_bian);
       //X轴从图形区域最左端到最右端
       double bottomY=0;
       double leftX=0;
       //bottomY表示X轴的y值,leftX表示Y轴的x值
       if(minY>0)
              bottomY=minY;
       if(minX>0)
              leftX=minX;
       pDC->MoveTo(int(myleft),int(height-(mybottom+(bottomY-minY)*intervalY)));
       pDC->LineTo(int(width-myright+topextend),int(height-(mybottom+(bottomY-minY)*intervalY)));
       pDC->LineTo(int(width-myright+topextend-10),int(height-(mybottom+(bottomY-minY)*intervalY)-5));
	   pDC->MoveTo(int(width-myright+topextend),int(height-(mybottom+(bottomY-minY)*intervalY)));
       pDC->LineTo(int(width-myright+topextend-10),int(height-(mybottom+(bottomY-minY)*intervalY)+5));


       //Y轴从图形区域最底端到最顶端
       pDC->MoveTo(int(myleft+(leftX-minX)*intervalX),int(height-mybottom));
       pDC->LineTo(int(myleft+(leftX-minX)*intervalX),int(mytop-topextend));
	   pDC->LineTo(int(myleft+(leftX-minX)*intervalX-5),int(mytop-topextend+10));
       pDC->MoveTo(int(myleft+(leftX-minX)*intervalX),int(mytop-topextend));
	   pDC->LineTo(int(myleft+(leftX-minX)*intervalX+5),int(mytop-topextend+10));
	   //绘制刻度和刻度值
       CString str;
       //X轴
	   	poldpen3=pDC->SelectObject(&pen_grid);
		 const int count=10;
        //确定每个显示刻度之间的宽度
       double spaceX=(width-myleft-myright)/count;
      double spaceY=(height-mybottom-mytop)/count;
       for(i=1;i<count+1;i++)
       {
              str.Format("%.1f",/*minX+i*(maxX-minX)/count*/i*maxX/count);
              pDC->MoveTo(int(myleft+spaceX*i),int(height-(mybottom+(bottomY-minY)*intervalY)));
              //pDC->LineTo(int(myleft+spaceX*i),int(height-(mybottom+(bottomY-minY)*intervalY+5)));
			  pDC->LineTo(int(myleft+spaceX*i),int(height-(mybottom+spaceY*count)));
              pDC->TextOut(int(myleft+spaceX*i-10),
              int(height-(mybottom+(bottomY-minY)*intervalY-5)),str);
       } 
       //Y轴
       for(i=1;i<=count;i++)
       {
             str.Format("%.1f",/*minY+i*(maxY-minY)/count*/i*maxY/count);
              pDC->MoveTo(int(myleft+(leftX-minX)*intervalX),int(height-(mybottom+spaceY*i)));
              pDC->LineTo(int(width-myright),int(height-(mybottom+spaceY*i)));
              pDC->TextOut(int(myleft+(leftX-minX)*intervalX-30),
                     int(height-(mybottom+spaceY*i+8)),str);
       }
       //绘制X,Y轴的变量名
       pDC->TextOut(width-80,height,"时间(t)");
       pDC->TextOut(20,height-290,"Y(t)");	   
	   pDC->SelectObject(poldpen1);	 	
       //绘制曲线。由于绘图坐标的Y轴是向下延升,所以这里每个点的Y值是用图象高度减去y值大小。
	   poldpen2=pDC->SelectObject(&pen_bian2);
       pDC->MoveTo(int(myleft), 
	   int(height-(mybottom+YI[0]*intervalY)));
	   pDC->LineTo(int(myleft+initX[0]*intervalX), 
	   int(height-(mybottom+YI[1]*intervalY)));
       for(i=1;i<num;i++)
       {
		   pDC->LineTo(int(myleft+initX[i]*intervalX), 
		   int(height-(mybottom+YI[i]*intervalY)));
       } 
   
}

void CPIDDlg::OnConfig() 
{
	// TODO: Add your control notification handler code here
  
 
   CWnd* pWnd=GetDlgItem(IDC_STATIC_SHOW);	
	pWnd->Invalidate();
	pWnd->UpdateWindow();
	CDC *pDC=pWnd->GetDC();
//	pDC->SetBkColor(RGB(0,255,255));
	CPen pen_bian,*poldpen1;
	pen_bian.CreatePen(PS_SOLID,2,RGB(0,0,255));

	poldpen1=pDC->SelectObject(&pen_bian);

    CPen pen_bian2,*poldpen2;
   	pen_bian2.CreatePen(PS_SOLID,1,RGB(255,0,0));
	poldpen2=pDC->SelectObject(&pen_bian2);

	CPen pen_grid,*poldpen3;
	pen_grid.CreatePen(PS_DOT,1,RGB(0,0,255));
	const int num=100;
    double initX[num];//={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
    double initY[num];//={2,5,1,8,8,17,25,35.2,40.1,50,33.3,28.4,22.2,24.1,26.2,18.3,14.1,24.7,18,6};
	//分别取得X和Y最大值,最小值
	initX[0]=0;
	initY[0]=0;
	 for(int i=0;i<num;i++)
	 {
		 initX[i]=i+1;
		 initY[i]=i+1;
	 }
	UpdateData();
 	double U[num];
	   U[0]=0;
   double Y[num];
	    Y[0]=0;
	    Y[1]=0;
      for( i=2;i<num;i++)
	   {
		   U[i-1]=m_stepU0;		  
		  double a=(-1)*(m_sampleT)/(m_paramT1);
		  double b=(-2)*(m_sampleT)/(m_paramT1);
		  double c= exp(a);
		  double d= exp(b);
		   Y[i]=2*c*(Y[i-1])-d*(Y[i-2])+(m_paramK1)*(1-c+a*c)*(U[i-1])-(m_paramK1)*(1-c+a)*c*(U[i-2]);
		   YI[i]=Y[i];
	  }
       double maxX=initX[0];
       double minX=initX[0];
       double maxY=initY[0];
       double minY=initY[0];
       double MAXY=Y[0];
       double MINY=Y[0];
       for(  i=0;i<num;i++)
       {
              if(initX[i]>maxX)
                     maxX=initX[i];
              if(initX[i]<minX)
                     minX=initX[i];
              if(initY[i]>maxY)
                     maxY=initY[i];
              if(initY[i]<minY)
                     minY=initY[i];
			  if(Y[i]>MAXY)
			         MAXY=Y[i];
			  if(Y[i]<MINY)
			         MINY=Y[i];
       } 
// m_chuanxian=MAXY;	  
      //如果原点必须在X轴上,加上下面2行,否则注释掉
       if(minX>0)
              minX=0; 
       //如果原点必须在Y轴上,加上下面2行,否则注释掉
       if(minY>0)
              minY=0; 
       //确定图象显示大小
       int width=860;
       int height=300;
	    //确定坐标图四周预留的空白大小
      const int mytop=20;
      const int mybottom=20;
      const int myleft=80;
      const int myright=50;
	  const int topextend=20;
	  
        //确定X,Y轴每单位显示宽度
      double intervalX=(width-myleft-myright)/(maxX-minX);
      double intervalY=(height-mybottom-mytop)/(maxY-minY);
	  //绘制X,Y轴
	   	poldpen1=pDC->SelectObject(&pen_bian);
       //X轴从图形区域最左端到最右端
       double bottomY=0;
       double leftX=0;
       //bottomY表示X轴的y值,leftX表示Y轴的x值
       if(minY>0)
              bottomY=minY;
       if(minX>0)
              leftX=minX;
       pDC->MoveTo(int(myleft),int(height-(mybottom+(bottomY-minY)*intervalY)));
       pDC->LineTo(int(width-myright+topextend),int(height-(mybottom+(bottomY-minY)*intervalY)));
       pDC->LineTo(int(width-myright+topextend-10),int(height-(mybottom+(bottomY-minY)*intervalY)-5));
	   pDC->MoveTo(int(width-myright+topextend),int(height-(mybottom+(bottomY-minY)*intervalY)));
       pDC->LineTo(int(width-myright+topextend-10),int(height-(mybottom+(bottomY-minY)*intervalY)+5));


       //Y轴从图形区域最底端到最顶端
       pDC->MoveTo(int(myleft+(leftX-minX)*intervalX),int(height-mybottom));
       pDC->LineTo(int(myleft+(leftX-minX)*intervalX),int(mytop-topextend));
	   pDC->LineTo(int(myleft+(leftX-minX)*intervalX-5),int(mytop-topextend+10));
       pDC->MoveTo(int(myleft+(leftX-minX)*intervalX),int(mytop-topextend));
	   pDC->LineTo(int(myleft+(leftX-minX)*intervalX+5),int(mytop-topextend+10));
	   //绘制刻度和刻度值
       CString str;
       //X轴
	   	poldpen3=pDC->SelectObject(&pen_grid);
		 const int count=10;
        //确定每个显示刻度之间的宽度
       double spaceX=(width-myleft-myright)/count;
      double spaceY=(height-mybottom-mytop)/count;
       for(i=1;i<count+1;i++)
       {
              str.Format("%.1f",/*minX+i*(maxX-minX)/count*/i*maxX/count);
              pDC->MoveTo(int(myleft+spaceX*i),int(height-(mybottom+(bottomY-minY)*intervalY)));
              //pDC->LineTo(int(myleft+spaceX*i),int(height-(mybottom+(bottomY-minY)*intervalY+5)));
			  pDC->LineTo(int(myleft+spaceX*i),int(height-(mybottom+spaceY*count)));
              pDC->TextOut(int(myleft+spaceX*i-10),
              int(height-(mybottom+(bottomY-minY)*intervalY-5)),str);
       } 
       //Y轴
       for(i=1;i<=count;i++)
       {
             str.Format("%.1f",/*minY+i*(maxY-minY)/count*/i*maxY/count);
              pDC->MoveTo(int(myleft+(leftX-minX)*intervalX),int(height-(mybottom+spaceY*i)));
              pDC->LineTo(int(width-myright),int(height-(mybottom+spaceY*i)));
              pDC->TextOut(int(myleft+(leftX-minX)*intervalX-30),
                     int(height-(mybottom+spaceY*i+8)),str);
       }
       //绘制X,Y轴的变量名
       pDC->TextOut(width-80,height,"时间(t)");
       pDC->TextOut(20,height-290,"Y(t)");	   
	   pDC->SelectObject(poldpen1);	 	
       //绘制曲线。由于绘图坐标的Y轴是向下延升,所以这里每个点的Y值是用图象高度减去y值大小。
	   poldpen2=pDC->SelectObject(&pen_bian2);
       pDC->MoveTo(int(myleft), 
	   int(height-(mybottom+YI[0]*intervalY)));
	   pDC->LineTo(int(myleft+initX[0]*intervalX), 
	   int(height-(mybottom+YI[1]*intervalY)));
       for(i=1;i<num;i++)
       {
		   pDC->LineTo(int(myleft+initX[i]*intervalX), 
		   int(height-(mybottom+YI[i]*intervalY)));
       } 
   	
}
void CPIDDlg::OnChuandi() 
{
	// TODO: Add your control notification handler code here

	UpdateData(false);
}
void CPIDDlg::OnCancel() 
{
	// TODO: Add extra cleanup here
 	CDialog::OnCancel();
}

⌨️ 快捷键说明

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