//--------------------------------------------------------------------------------------------------
//数学模型小作业(快艇追赶模型)
//题目描述:
//01.参考书目:ISBN 978-7-04-028567-3.ISBN 7-309-04306-5.ISBN 978-7-04-014421-5.
//01.为了简化模型,作了下面的假设:
//02.走私船A以速度a平行于x轴正向行驶;缉私船B以速度b沿走私船的方向行驶;任意时刻缉私船航向总是指向走私船,且速度b>a.
//03.假设经过时刻t,A艇位于Q(a*t,c),B艇位于P(x,y).
//04.缉私艇在x,y方向的分速度为:(dx/dt)=b*sin(α),(dy/dt)=b*cos(α).
//05.在三角形ΔPQR中,sin(α)=(a*t-x)/sqrt((a*t-x)^2+(c-y)^2);cos(α)=(c-y)/sqrt((a*t-x)^2+(c-y)^2).
//06.得到:(dx/dt)=b*(a*t-x)/sqrt((a*t-x)^2+(c-y)^2);(dy/dt)=b*(c-y)/sqrt((a*t-x)^2+(c-y)^2).
//07.试利用数值解法求解此方程.
//程序编制要求:
//1.两船的距离c,船A的航速va,船B航速vb..
//2.计算相遇的时间,两船各自行进的路程(只讨论vb>va的情况).
//3.绘制速度距离示意图.
//--------------------------------------------------------------------------------------------------------------------
#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 10//宏定义x轴刻度数量
#define ny 10//宏定义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,255,0)//颜色4
#define c5 RGB(0,255,255)//颜色5
#define c6 RGB(0,255,0)//颜色6
//曲线颜色------------------------------------------
#define cc1 RGB(0,255,255)//宏定义曲线颜色4(青色)
#define cc2 RGB(0,255,0)//宏定义曲线颜色2(绿色)
#define cc3 RGB(255,255,0)//宏定义曲线颜色3(黄色)
#define cc4 RGB(0,255,100)//宏定义曲线颜色1(红色)
#define cc5 RGB(255,100,0)//宏定义曲线颜色5(青色)
//定义结构体-------------------------------------------------------------------------------------------------------
typedef struct points
{
double x,y;//定义双精度变量
}DPOINT;//结束结构体
//窗口全局变量-----------------------------------------------------------------------------------------------------
int W = GetSystemMetrics(SM_CXSCREEN);//获取整个屏幕右下角X坐标
int H = GetSystemMetrics(SM_CYSCREEN);//屏幕Y坐标
int c_h=36;//定义控件高度
//数据全局变量
char is1[20]="1000.0";//预定义:1.两船距离C(m)
char is2[20]="10.0";//2.船A速度va(m/s)
char is3[20]="20";//3.船B速度vb(m/s)
char is7[20]="20.0";//7.输入时间(s)
char is4[20],is5[20],is6[20],is8[20],is9[20],is10[20],is11[20];//定义字符数组(存储字符串)
double d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11;//(存储计算值)
int i,j,k;//
double value;//定义双精度变量
char stt[10];//定义字符数组
//函数声明---------------------------------------------------------------------------------------------------------
void sub_frame();//绘制框架子函数
void sub_calculate();//计算数据子函数
void func_XY(double tt,double *x,double *y,double *s);//根据时间返回行驶距离
//主函数-----------------------------------------------------------------------------------------------------------
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.两船距离C(m):-----------------------------------------------------
if(m.y>=H-DH-16*c_h+1 && m.y<=H-DH-15*c_h-1)//
{
InputBox(is1,9,"请输入数据");//读入数据
setfillcolor(BLACK);
fillrectangle(W-DW-DC+DC/2+10,H-DH-16*c_h+1,W-DW,H-DH-15*c_h);
outtextxy(W-DW-DC+DC/2+15,H-DH-16*c_h+15,is1);//写控件字符串
}//结束if
//2.船A速度va(m/s):-----------------------------------------------------
if(m.y>=H-DH-15*c_h+1 && m.y<=H-DH-14*c_h-1)//
{
InputBox(is2,9,"请输入数据");//读入数据
setfillcolor(BLACK);
fillrectangle(W-DW-DC+DC/2+10,H-DH-15*c_h+1,W-DW,H-DH-14*c_h);
outtextxy(W-DW-DC+DC/2+15,H-DH-15*c_h+15,is2);//写控件字符串
}//结束if
//3.船B速度vb(m/s):-----------------------------------------------------
if(m.y>=H-DH-14*c_h+1 && m.y<=H-DH-13*c_h-1)//
{
InputBox(is3,9,"请输入数据");//读入数据
setfillcolor(BLACK);
fillrectangle(W-DW-DC+DC/2+10,H-DH-14*c_h+1,W-DW,H-DH-13*c_h);
outtextxy(W-DW-DC+DC/2+15,H-DH-14*c_h+15,is3);//写控件字符串
}//结束if
//7.输入时间(s):-----------------------------------------------------
if(m.y>=H-DH-10*c_h+1 && m.y<=H-DH-9*c_h-1)//
{
InputBox(is7,9,"请输入数据");//读入数据
setfillcolor(BLACK);
fillrectangle(W-DW-DC+DC/2+10,H-DH-10*c_h+1,W-DW,H-DH-9*c_h);
outtextxy(W-DW-DC+DC/2+15,H-DH-10*c_h+15,is7);//写控件字符串
}//结束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);//控件区域边框
//5.输出标题
setfont(16,0,"黑体");
outtextxy(5,10,"数学模型小作业(快艇追赶模型)");
//6.输出简单说明
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~3为输入数据 4~11为计算数据\n\
\n\n\
\n\n\
\
\n", &r, DT_WORDBREAK);//
//7.调整说明文字下面的矩形控件
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
//8.绘制控件说明文字
outtextxy(c_x1+10,H-DH-16*c_h+15,"1.两船距离C(m):");//输出字符串模拟控件文字
outtextxy(c_x1+10,H-DH-15*c_h+15,"2.船A速度va(m/s):");//输出字符串模拟控件文字
outtextxy(c_x1+10,H-DH-14*c_h+15,"3.船B速度vb(m/s):");//输出字符串模拟控件文字
outtextxy(c_x1+10,H-DH-13*c_h+15,"4.追逐时间t(s):");//输出字符串模拟控件文字
outtextxy(c_x1+10,H-DH-12*c_h+15,"5.船A行驶距离(m):");//输出字符串模拟控件文字
outtextxy(c_x1+10,H-DH-11*c_h+15,"6.船B行驶距离(m):");//输出字符串模拟控件文字
outtextxy(c_x1+10,H-DH-10*c_h+15,"7.输入时间(s):");//输出字符串模拟控件文字
outtextxy(c_x1+10,H-DH-9*c_h+15,"8.船B地点x(m):");//输出字符串模拟控件文字
outtextxy(c_x1+10,H-DH-8*c_h+15,"9.船B地点y(m):");//输出字符串模拟控件文字
outtextxy(c_x1+10,H-DH-7*c_h+15,"10.行驶距离(m):");//输出字符串模拟控件文字
outtextxy(c_x1+10,H-DH-6*c_h+15,"11.两船相距(m):");//输出字符串模拟控件文字
//8.初始化原始数据
outtextxy(W-DW-DC+DC/2+35,H-DH-16*c_h+15,is1);//写控件字符串
outtextxy(W-DW-DC+DC/2+35,H-DH-15*c_h+15,is2);//写控件字符串
outtextxy(W-DW-DC+DC/2+35,H-DH-14*c_h+15,is3);//写控件字符串
outtextxy(W-DW-DC+DC/2+35,H-DH-10*c_h+15,is7);//写控件字符串
}//结束子程序
//计算数据子函数
void sub_calculate()
{
//1.原始数据转化为双精度数
d1=atof(is1);//1.两船距离C(m)
d2=atof(is2);//2.船A速度va(m/s)
d3=atof(is3);//3.船B速度vb(m/s)
d7=atof(is7);//7.输入时间(s)
//2.根据数据计算要求项目---------------------------------------------------------------------------
double kt=0,x0=0,y0=0,x1=0,y1=0,s1=0;
while(sqrt((x1-d2*kt)*(x1-d2*kt)+(y1-d1)*(y1-d1)) >= 10.0)//认为追逐成功
{
func_XY(kt,&x1,&y1,&s1);//
kt=kt+1;//
}//
d4=kt;//4.追逐时间t(s)
d5=d4*d2;//5.船A行驶距离(m)
func_XY(d4,&x1,&y1,&d6);//6.船B行驶距离(m)
//cout<<d4<<endl;
func_XY(d7,&d8,&d9,&d10);8.船B地点x(m)//9.船B地点y(m)//10.行驶距离(m)
d11=sqrt((d8-d7*d2)*(d8-d7*d2)+(d9-d1)*(d9-d1));//11.两船相距(m)
//3.将计算结果转化为字符串--------------------------------------------------------------------------
gcvt(d4,4,is4);//
gcvt(d5,4,is5);//
gcvt(d6,4,is6);//
gcvt(d8,4,is8);//
gcvt(d9,4,is9);//
gcvt(d10,4,is10);//
gcvt(d11,4,is11);//
//4.将字符串写入控件中
setfillcolor(BLACK);
//------------------------------------------------------------
fillrectangle(W-DW-DC+DC/2+40,H-DH-13*c_h+1,W-DW,H-DH-12*c_h);
outtextxy(W-DW-DC+DC/2+45,H-DH-13*c_h+15,is4);//写控件字符串
//------------------------------------------------------------
fillrectangle(W-DW-DC+DC/2+40,H-DH-12*c_h+1,W-DW,H-DH-11*c_h);
outtextxy(W-DW-DC+DC/2+45,H-DH-12*c_h+15,is5);//写控件字符串
//------------------------------------------------------------
fillrectangle(W-DW-DC+DC/2+40,H-DH-11*c_h+1,W-DW,H-DH-10*c_h);
outtextxy(W-DW-DC+DC/2+45,H-DH-11*c_h+15,is6);//写控件字符串
//------------------------------------------------------------
fillrectangle(W-DW-DC+DC/2+40,H-DH-9*c_h+1,W-DW,H-DH-8*c_h);
outtextxy(W-DW-DC+DC/2+45,H-DH-9*c_h+15,is8);//写控件字符串
//------------------------------------------------------------
fillrectangle(W-DW-DC+DC/2+40,H-DH-8*c_h+1,W-DW,H-DH-7*c_h);
outtextxy(W-DW-DC+DC/2+45,H-DH-8*c_h+15,is9);//写控件字符串
//------------------------------------------------------------
fillrectangle(W-DW-DC+DC/2+40,H-DH-7*c_h+1,W-DW,H-DH-6*c_h);
outtextxy(W-DW-DC+DC/2+45,H-DH-7*c_h+15,is10);//写控件字符串
//------------------------------------------------------------
fillrectangle(W-DW-DC+DC/2+40,H-DH-6*c_h+1,W-DW,H-DH-5*c_h);
outtextxy(W-DW-DC+DC/2+45,H-DH-6*c_h+15,is11);//写控件字符串
//------------------------------------------------------------
setcolor(cc1);//说明曲线颜色
line(W-DW-DC-200,H-DH-3*c_h+10,W-DW-DC-260,H-DH-3*c_h+10);
outtextxy(W-DW-DC-200+15,H-DH-3*c_h+5,"1.t-x航迹");//写控件字符串
//------------------------------------------------------------
setcolor(cc2);//说明曲线颜色
line(W-DW-DC-200,H-DH-2*c_h+10,W-DW-DC-260,H-DH-2*c_h+10);
outtextxy(W-DW-DC-200+15,H-DH-2*c_h+5,"2.t-y航迹");//写控件字符串
//------------------------------------------------------------
setcolor(cc3);//说明曲线颜色
line(W-DW-DC-200,H-DH-1*c_h+10,W-DW-DC-260,H-DH-1*c_h+10);
outtextxy(W-DW-DC-200+15,H-DH-1*c_h+5,"3.XY-航迹");//写控件字符串
//------------------------------------------------------------
//5.绘制工作区坐标线
//画x轴刻度标线及文字(时间t)---------------------------
double xstep=(W-2*DW-DC)/(1.0*nx);//x方向步长(nx个刻度)(对应的绘图单位)
double ystep=(H-DH-DD)/(1.0*ny);//y方向步长(ny个刻度)(对应的绘图单位)
double x_scale1=(W-2*DW-DC)*1.0/(1.0*d4);//时间单位
double x_scale2=(W-2*DW-DC)*1.0/(1.0*d5);//x单位
double y_scale=(H-DH-DD)*1.0/(1.0*d1);//y单位
//画x1轴
for(i=0;i<=nx;i++)
{
setcolor(c1);//竖直辅助线颜色
line(DW+xstep*i,H-DH,DW+xstep*i,DD);//画竖直小刻度线
setcolor(c3);//文字颜色
//x1轴(时间t)---------------------------------------------------
setcolor(cc2);//竖直辅助线颜色
value=i*d4/(1.0*nx);//所在的刻度数值
gcvt(value,6,stt);//将浮点数value转换为字符串stt
outtextxy(DW+xstep*i-10,H-DH-20,stt);//在规定的位置放置字符串
//x2轴(距离s)---------------------------------------------------
setcolor(cc3);//竖直辅助线颜色
value=i*d5/(1.0*nx);//所在的刻度数值
gcvt(value,6,stt);//将浮点数value转换为字符串stt
outtextxy(DW+xstep*i-10,DD+20,stt);//在规定的位置放置字符串
}//结束for
//画y轴刻度标线及文字(距离)---------------------------
for(i=0;i<=ny;i++)
{
setcolor(c2);//水平辅助线颜色
line(DW,DD+ystep*i,W-DW-DC,DD+ystep*i);//画水平小刻度线
setcolor(cc3);//文字颜色
value=(ny-i)*(1.0*d1)/ny;//所在的刻度数值
gcvt(value,5,stt);//将浮点数value转换为字符串stt
outtextxy(DW+15,DD+ystep*i-10,stt);//在规定的位置放置字符串
}//结束for
//绘制点位-----------------------------------------------------------
setcolor(RED);//三个坐标轴颜色
//[Q点]
line(DW+(d7*d2*x_scale2)-5,DD,DW+(d7*d2*x_scale2)+5,DD);
line(DW+(d7*d2*x_scale2),DD-5,DW+(d7*d2*x_scale2),DD+5);
//[P点]
line(DW+(d8*x_scale2)-5,H-DH-d9*y_scale,DW+(d8*x_scale2)+5,H-DH-d9*y_scale);
line(DW+(d8*x_scale2),H-DH-d9*y_scale-5,DW+(d8*x_scale2),H-DH-d9*y_scale+5);
//[tx点]
line(DW+(d7*x_scale1)-5,H-DH-d8*y_scale,DW+(d7*x_scale1)+5,H-DH-d8*y_scale);
line(DW+(d7*x_scale1),H-DH-d8*y_scale-5,DW+(d7*x_scale1),H-DH-d8*y_scale+5);
//[ty点]
line(DW+(d7*x_scale1)-5,H-DH-d9*y_scale,DW+(d7*x_scale1)+5,H-DH-d9*y_scale);
line(DW+(d7*x_scale1),H-DH-d9*y_scale-5,DW+(d7*x_scale1),H-DH-d9*y_scale+5);
//[PQ]两点连线
line(DW+(d7*d2*x_scale2),DD,DW+(d8*x_scale2),H-DH-d9*y_scale);
setcolor(cc2);
line(DW+(d8*x_scale2)-10,H-DH-d9*y_scale,DW,H-DH-d9*y_scale);
setcolor(cc1);
line(DW+(d8*x_scale2),H-DH-d9*y_scale-10,DW+(d8*x_scale2),DD);
setcolor(RED);//三个坐标轴颜色
setfont(20,0,"黑体");
outtextxy(DW+(d7*d2*x_scale2)-5,DD-30,"Q");//点Q
outtextxy(DW+(d8*x_scale2)+10,H-DH-d9*y_scale+10,"P");//点P
//6.重新绘制工作区边框
setcolor(c3);
rectangle(DW,DD,W-DW,H-DH);//外边框
rectangle(W-DW-DC,DD,W-DW,H-DH);//控件区域边框
//------------------------------------------------------------
//7.获取时间变化时的变化曲线------------------------------------------------
double n1,n2,n3;//
DPOINT *p1;//1.对应t-x
DPOINT *p2;//2.对应t-y
DPOINT *p3;//3.对应x-y
p1=new DPOINT[10000];//定义N1点表
p2=new DPOINT[10000];//定义N2点表
p3=new DPOINT[10000];//定义N3点表
for(j=0;j<=d4*10.0;j++)//时间范围
{
double tt=j*0.1;//时间范围
func_XY(tt,&n1,&n2,&n3);//
p1[j].x=DW+tt*x_scale1;
p1[j].y=H-DH-n1*y_scale;
p2[j].x=DW+tt*x_scale1;
p2[j].y=H-DH-n2*y_scale;
p3[j].x=DW+n1*x_scale2;
p3[j].y=H-DH-n2*y_scale;
//cout<<n1<<" "<<n2<<endl;
}//结束for
//8.绘制时间变化时的变化曲线---------------------------------------------------
setcolor(cc1);//曲线颜色1
for(j=0;j<=d4*10.0-1;j++)//
{
line(p1[j].x,p1[j].y,p1[j+1].x,p1[j+1].y);//
}//结束for
setcolor(cc2);//曲线颜色2
for(j=0;j<=d4*10.0-1;j++)//
{
line(p2[j].x,p2[j].y,p2[j+1].x,p2[j+1].y);//
}//结束for
setcolor(cc3);//曲线颜色3
for(j=0;j<=d4*10.0-1;j++)//
{
line(p3[j].x,p3[j].y,p3[j+1].x,p3[j+1].y);//
}//结束for
}//结束子函数
void func_XY(double tt,double *x,double *y,double *s)//根据时间返回行驶距离
{
int i=0;//
double x0,y0,ds,x1,y1,dx,dy;//
x0=0;//
y0=0;//
ds=0;//
*x=0;//
*y=0;//
*s=0;//
for(i=0;i<=tt*10;i++)//对每个时刻微段
{
double cc=sqrt((d2*i*0.1-x0)*(d2*i*0.1-x0)+(d1-y0)*(d1-y0));//中间变量
dx=0.1*d3*(d2*i*0.1-x0)/cc;//
dy=0.1*d3*(d1-y0)/cc;//
ds=sqrt(dx*dx+dy*dy);//
*s=(*s)+ds;//
x1=x0+dx;//
y1=y0+dy;//
x0=x1;//
y0=y1;
}//结束for
*x=x0;//
*y=y0;//
}//结束子函数
//*/
//--------------------------------------------------------------------------------------------------
数学模型小作业(快艇追赶模型)
于 2023-12-13 09:10:43 首次发布