数学模型小作业(杆子如何通过走廊的直角拐角)

//数学模型小作业(杆子如何通过走廊的直角拐角)
//题目描述:
//1.假设直角拐角的宽度分别为a,b.
//题目要求:能够通过这个拐角的最大杆长Lmax和对应的角度θ.
//题目分析:
//01.详见<<数学建模>>(ISBN-978-7-5095-2639-2/0.0028) Page48~49.
//02.θ=atan((b/a)^(1/3))时,Lmax=(a^(2/3)+b^(2/3))^(3/2).
//程序编制要求:
//1.直角拐角宽度a,b交互读取.
//2.计算能够通过这个拐角的最大杆长Lmax和对应的角度θ.
//--------------------------------------------------------------------------------------------------------------------
#include <graphics.h>//包含Easyx模拟TC的BGI绘图库头文件
#include <math.h>//包含数学运算头文件
#include <iostream.h>//
#define DD 40//宏定义标题边框距离
#define DW 10//宏定义宽度边框距离
#define DH 10//宏定义高度边框距离
#define DC 200//宏定义控件区域宽度
#define nx 8//宏定义x轴刻度数量
#define ny 8//宏定义y轴刻度数量
#define PI 3.1415926//宏定义圆周率
#define c1 RGB(38,47,86)//宏定义辅助线颜色1
#define c2 RGB(38,47,86)//宏定义辅助线颜色2
#define c3 RGB(255,255,255)//宏定义文字及边框颜色
#define c4 RGB(255,0,0)//宏定义曲线颜色1(红色)
#define c5 RGB(0,255,0)//宏定义曲线颜色2(绿色)
#define c6 RGB(0,0,255)//宏定义曲线颜色3(蓝色)
//定义结构体-------------------------------------------------------------------------------------------------------
typedef struct points
{
	double x,y;//定义双精度变量
}DPOINT;//结束结构体
//定义全局变量-----------------------------------------------------------------------------------------------------
int W = GetSystemMetrics(SM_CXSCREEN);//获取整个屏幕右下角X坐标
int H = GetSystemMetrics(SM_CYSCREEN);//屏幕Y坐标 
char is1[20]="3";//预定义:1.宽度a(m)
char is2[20]="4";//2.宽度b(m)
char is3[20],is4[20];//定义字符数组(存储字符串)
double d1,d2,d3,d4,d5,d6,d7;//定义双精度变量(存储计算值)
//函数声明---------------------------------------------------------------------------------------------------------
void sub_frame();//绘制框架子函数
void sub_calculate();//计算数据子函数
//主函数-----------------------------------------------------------------------------------------------------------
void main()
{
	sub_frame();//绘图初始化
	MOUSEMSG m;//定义鼠标消息 
	while(true)//循环
	{
		m=GetMouseMsg();//获取一条鼠标消息 
		switch(m.uMsg)//根据获得的消息选择分支
		{
		case WM_LBUTTONDOWN://鼠标左键单击时判断数据输入
			{
				//判断鼠标位置是否在指定的控件区域
				//A.获取原始数据(横坐标在输入区域时输入数据)-------------------------------
				if(m.x>=W-DW-DC && m.x<=W-DW)
				{
					//1.宽度a(m):------------------------------------------------------
					if(m.y>=H-DH-16*36+1 && m.y<=H-DH-15*36-1)//
					{
						InputBox(is1,9,"请输入数据");//读入数据
						setfillcolor(BLACK);
						fillrectangle(W-DW-DC+DC/2+10,H-DH-16*36+1,W-DW,H-DH-15*36);
						outtextxy(W-DW-DC+DC/2+15,H-DH-16*36+15,is1);//写控件字符串
					}//结束if
					//2.宽度b(m):-----------------------------------------------------
					if(m.y>=H-DH-15*36+1 && m.y<=H-DH-14*36-1)//
					{
						InputBox(is2,9,"请输入数据");//读入数据
						setfillcolor(BLACK);
						fillrectangle(W-DW-DC+DC/2+10,H-DH-15*36+1,W-DW,H-DH-14*36);
						outtextxy(W-DW-DC+DC/2+15,H-DH-15*36+15,is2);//写控件字符串
					}//结束if
				}//结束if(横坐标在输入区域时输入数据)
				sub_frame();//重绘框架
				//B.计算并绘图(横坐标在绘图区域时计算绘图)---------------------------------
				if(m.x>=DW && m.x<=W-DW-DC)
				{
					sub_calculate();//调用计算绘图函数
				}//结束if
				break;//
			}//结束case(结束鼠标左键单击事件消息处理)
		case WM_RBUTTONDOWN://鼠标移动的时候画个空心的圆
			return;//返回while
		}//结束switch(结束鼠标消息)
	}//结束while
}//结束主函数
//绘制框架子函数
void sub_frame()
{
	//1.全屏效果---------------------------------------------------------------------------
	initgraph(W,H);//初始化绘图窗口
	HWND hWnd = GetHWnd();//获取窗口句柄
	LONG style = GetWindowLong(hWnd,-16);//获得窗口风格
	style = style & ~WS_CAPTION & ~WS_SIZEBOX; //窗口全屏显示且不可改变大小
	SetWindowLong(hWnd,-16,style);//设置窗口风格
	SetWindowPos(hWnd, NULL,0,0,W,H,SWP_NOZORDER);//改变窗口位置,尺寸和Z序
	//ShowCursor(FALSE);//显示时隐藏鼠标
	//------------------------------------------------------------------------------------
	//2.绘制工作区边框
	setcolor(c3);
	rectangle(DW,DD,W-DW,H-DH);//外边框
	rectangle(W-DW-DC,DD,W-DW,H-DH);//控件区域边框
	//3.输出标题
	setfont(16,0,"黑体");
	outtextxy(5,10,"数学模型小作业(杆子如何通过走廊的直角拐角)");
	//4.输出简单说明
	RECT r={W-DW-DC+10,DD+10,W-DW-10,H-DH-10};//
	setfont(12,0,"宋体");//
	drawtext("数学模型小作业:\n \n \
				杆子如何通过走廊的直角拐角\
				\
				\n\n\
				操作说明:\n\n\
				鼠标左键  : 数据输入\n\
				鼠标右键  : 退出程序\n\
			\n\
			1~2为输入数据   3~4为计算数据\n\
			\n\n\
			\n\n\
			\
			\n", &r, DT_WORDBREAK);//
	//5.调整说明文字下面的矩形控件
	int c_h=36;//定义控件高度
	int c_x1=W-DW-DC,c_x2=W-DW;//控件左右x坐标
	int c_y1=H-DH;//第1个控件下y坐标
	for(int i=1;i<=16;i++)
	{
		rectangle(c_x1,c_y1,c_x2,c_y1-c_h);//
		c_y1=c_y1-c_h;
	}//结束for
	//6.绘制控件说明文字
	outtextxy(c_x1+10,H-DH-16*c_h+15,"1.宽度a(m):");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-15*c_h+15,"2.宽度b(m):");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-14*c_h+15,"3.角度θ(°):");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-13*c_h+15,"4.最大杆长(m):");//输出字符串模拟控件文字
	//7.初始化原始数据
	outtextxy(W-DW-DC+DC/2+15,H-DH-16*36+15,is1);//写控件字符串
	outtextxy(W-DW-DC+DC/2+15,H-DH-15*36+15,is2);//写控件字符串
}//结束子程序
//计算数据子函数
void sub_calculate()
{
	//1.原始数据转化为双精度数
	d1=atof(is1);//1.宽度a(m)
	d2=atof(is2);//2.宽度b(m)
	//2.根据数据计算要求项目---------------------------------------------------------------------------
	d3=atan(pow(1.0*d2/d1,1.0/3.0))*180.0/PI;//3.角度θ(°)
	d4=pow((pow(d1,2.0/3.0)+pow(d2,2.0/3.0)),3.0/2.0);//4.最大杆长(m)
	d5=d1>d2?d1:d2;//取大值
	d6=d2+d1*pow(1.0*d2/d1,1.0/3.0);//与竖直拐角交点
	d7=d1+(1.0*d2)/pow(1.0*d2/d1,1.0/3.0);//与水平拐角交点
	//3.将计算结果转化为字符串--------------------------------------------------------------------------
	gcvt(d3,6,is3);//
	gcvt(d4,6,is4);//
	//4.将字符串写入控件中
	setfillcolor(BLACK);
	//------------------------------------------------------------
	fillrectangle(W-DW-DC+DC/2+10,H-DH-14*36+1,W-DW,H-DH-13*36);
	outtextxy(W-DW-DC+DC/2+15,H-DH-14*36+15,is3);//写控件字符串
	//------------------------------------------------------------
	fillrectangle(W-DW-DC+DC/2+10,H-DH-13*36+1,W-DW,H-DH-12*36);
	outtextxy(W-DW-DC+DC/2+15,H-DH-13*36+15,is4);//写控件字符串
	//------------------------------------------------------------
	//5.绘制工作区坐标线
	//画x轴刻度标线及文字---------------------------
	double value;//定义双精度变量
	char stt[10];//定义字符数组
	double xstep=(W-2*DW-DC)/(1.0*nx);//x方向步长(nx个刻度)(对应的绘图单位)
	double ystep=(H-DH-DD)/(1.0*ny);//y方向步长(ny个刻度)(对应的绘图单位)
	for(int i=0;i<=nx;i++)
	{
		setcolor(c1);//竖直辅助线颜色
		line(DW+xstep*i,H-DH,DW+xstep*i,DD);//画竖直小刻度线
		setcolor(c3);//文字颜色
		value=xstep*i*4*d5/(W-2*DW-DC);//所在的刻度数值
		gcvt(value,5,stt);//将浮点数value转换为字符串stt
		outtextxy(DW+xstep*i-10,H-DH-20,stt);//在规定的位置放置字符串
	}//结束for
	//画y轴刻度标线及文字---------------------------
	for(i=0;i<=ny;i++)
	{
		setcolor(c2);//水平辅助线颜色
		line(DW,DD+ystep*i,W-DW-DC,DD+ystep*i);//画水平小刻度线
		setcolor(c3);//文字颜色
		value=ystep*(ny-i)*4*d5/(H-DH-DD);//所在的刻度数值
		gcvt(value,3,stt);//将浮点数value转换为字符串stt
		outtextxy(DW+15,DD+ystep*i+5,stt);//在规定的位置放置字符串
	}//结束for
	//6.重新绘制工作区边框
	setcolor(c3);
	rectangle(DW,DD,W-DW,H-DH);//外边框
	rectangle(W-DW-DC,DD,W-DW,H-DH);//控件区域边框
	//7.绘制示意图------------------------------------------------
	double x_scale=(W-2*DW-DC)*1.0/(4.0*d5);//每个数学单位x对应的屏幕单位
	double y_scale=(H-DH-DD)*1.0/(4.0*d5);//每个数学单位y对应的屏幕单位
	//获取3个点的位置
	DPOINT p1;//拐角点
	DPOINT p2;//竖直拐角交点
	DPOINT p3;//水平拐角交点
	p1.x=DW+d1*x_scale;//
	p1.y=H-DH-d2*y_scale;//
	p2.x=DW;//
	p2.y=H-DH-d6*y_scale;//
	p3.x=DW+d7*x_scale;//
	p3.y=H-DH;//
	setcolor(c5);//曲线颜色1
	line(p1.x,p1.y,p1.x,DD);
	line(p1.x,p1.y,W-DW-DC,p1.y);
	setcolor(c6);//曲线颜色2
	line(p2.x,p2.y,p3.x,p3.y);
}//结束子函数*/
//--------------------------------------------------------------------------------------------------------------------

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一阶直线倒立摆是一个经典的控制系统模型,它由一个质量为$m$的小球连接一个质量为$M$的杆子组成,杆子垂直于水平面,小球可以沿着杆子的轨迹上下移动,系统的目标是使小球保持在竖直位置。 为了建立一阶直线倒立摆的数学模型,我们需要考虑以下几个方面: 1. 系统的动力学方程 运用牛顿第二定律和动量守恒定律,可以得到一阶直线倒立摆的动力学方程: $$ (M+m)\ddot{x}+ml\ddot{\theta}\cos\theta-ml\dot{\theta}^2\sin\theta=F $$ $$ ml\ddot{x}\cos\theta+ml^2\ddot{\theta}+(M+m)gl\sin\theta=0 $$ 其中,$x$表示小球的垂直位移,$\theta$表示杆子的倾斜角度,$l$表示杆子的长度,$g$表示重力加速度,$F$表示施加在小球上的外力。 2. 系统的状态空间方程 我们可以将动力学方程改写为状态空间方程的形式: $$ \begin{bmatrix}\dot{x}\\ \ddot{x}\\ \dot{\theta}\\ \ddot{\theta}\end{bmatrix} = \begin{bmatrix}0 & 1 & 0 & 0\\ 0 & 0 & -\frac{ml}{M+m} & 0\\ 0 & 0 & 0 & 1\\ 0 & 0 & \frac{g}{l(M+m)} & 0\end{bmatrix}\begin{bmatrix}x\\ \dot{x}\\ \theta\\ \dot{\theta}\end{bmatrix} + \begin{bmatrix}0\\ \frac{1}{M+m}\\ 0\\ -\frac{1}{l(M+m)}\end{bmatrix}F $$ 其中,状态向量为$[x,\dot{x},\theta,\dot{\theta}]^T$,状态矩阵为$A$,输入矩阵为$B$,输出矩阵为$C$。 3. 控制器设计 为了使小球保持竖直位置,我们需要设计一个控制器来控制外力$F$的大小和方向。常见的控制器包括PID控制器、状态反馈控制器等。 综上所述,建立一阶直线倒立摆的数学模型需要考虑系统的动力学方程、状态空间方程和控制器设计等方面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值