模拟小球抛物运动轨迹
一、实现抛物运动
1、新建一个工程,如下图所示。
2、新建一个类,取名“CPaoWu”,如下图所示。
3、双击“CPaoWu”,在它的头文件里给它定义一个pDC,并定义一些成员变量,代码如下。
class CPaoWu
{
public:
void Move();
void Draw(CDC *p);
CPaoWu();
virtual ~CPaoWu();
//下面开始添加代码
CDC *pDC; //之前画图都是用OnDraw()里的pDC,现在我们把它定义在类的内部来完成
int r; //定义圆的半径
int x,y; //物体用圆来表示
float vx,vy;//沿x,y轴的速度
int ax,ay;//沿x,y轴的加速度
int m; //小球质量
float DeltaT ;
float f,fx,fy; //阻力
float c; //外形阻力系数
float v;
float S; //物体横截面积
float Rho; //空气密度
};
4、我们添加一个Draw(CDC,*p)成员函数来画圆,如下图所示。
void CPaoWu::Draw(CDC *p) //面向对象的进一步封装
{
pDC = p;
pDC->Ellipse(x - r, y - r, x + r, y + r);
}
5、然后在CPaoWu()构造函数里给圆赋初值,代码如下。
CPaoWu::CPaoWu()
{
x = 100;
y = 500;
r = 30; //给圆赋初值
vx = 300;
vy = -200;
ax = 10;
ay = 8;
m = 80;
}
(记得在必要的地方嵌入#include "PaoWu.h"头文件!)
6、在CYunDongView类里添加消息响应句柄“WM_TIMER”,如下图所示。
7、然后添加菜单,并建立类向导,给它“开始”、“结束”加上命令消息,如下图所示。
8、在OnMStart()和OnMStop()里添加如下代码。
void CYunDongView::OnMStart()
{
// TODO: Add your command handler code here
SetTimer(1,50,NULL);
}
void CYunDongView::OnMStop()
{
// TODO: Add your command handler code here
KillTimer(1);
}
9、再让圆动起来,我们添加一个Move()函数,如下图所示。
代码如下:
void CPaoWu::Move()
{
DeltaT = 0.1;
v = sqrt(vx * vx + vy * vy);
f = c * Rho * S * v * v;
fx = f * vx/v; //sinθ = vx/v
fy = -f * vy/v;
ax = -fx/m; //x轴阻力加速度
ay = fy/m + 10; //y轴阻力加速度
vx += ax * DeltaT;
vy += ay * DeltaT;
x += vx * DeltaT;
y += vy * DeltaT;
}
10、在OnTimer()里调用Move()函数,代码如下。
void CYunDongView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
pw.Move(); //调用
Invalidate(TRUE); //重画
CView::OnTimer(nIDEvent);
}
11、到这儿,我们就已经完成了,整个结构如下图所示。
二、添加对话框改变参数
1、新建对话框,并添加以下控件,如下图所示。
注意:编辑框“属性 >> 样式”中的“数字”不要勾选,因为后面我们在设置一些参数的时候有可能用上小数、负数,勾选后就只能设置正整数了。
2、建立一个IDD_Dlg_SetPaoWuPara所对应的类,并添加成员变量,如下图所示。
3、添加一个“抛物运动参数设置”菜单,并添加命令消息,如下图所示。
4、在OnMSetPaoWuPara()中添加代码(记得嵌入头文件)。
void CYunDongView::OnMSetPaoWuPara()
{
// TODO: Add your command handler code here
CDlg_SetPaoWuPara dlg_setPaoWuPara;
if(dlg_setPaoWuPara.DoModal() == IDOK)
{
pw.x = dlg_setPaoWuPara.m_x;
pw.y = dlg_setPaoWuPara.m_y;
pw.r = dlg_setPaoWuPara.m_r;
pw.m = dlg_setPaoWuPara.m_m;
pw.vx = dlg_setPaoWuPara.m_vx;
pw.vy = dlg_setPaoWuPara.m_vy;
pw.c = dlg_setPaoWuPara.m_c;
pw.S = dlg_setPaoWuPara.m_S;
pw.Rho = dlg_setPaoWuPara.m_Rho;
Invalidate(TRUE);
}
}
5、此时的Move()代码如下,并附上部分代码界面截屏。
void CPaoWu::Move()
{
DeltaT = 0.1;
v = sqrt(vx * vx + vy * vy);
f = c * Rho * S * v * v;
fx = f * vx/v; //sinθ = vx/v
fy = -f * vy/v;
ax = -fx/m; //x轴阻力加速度
ay = fy/m + 10; //y轴阻力加速度
vx += ax * DeltaT;
vy += ay * DeltaT;
x += vx * DeltaT;
y += vy * DeltaT;
}
6、编译运行结果如下图所示。