VC6.0 MFC 模拟弹簧运动(改进版)
一、内容描述
运用VC6.0新建工程MFC AppWizard(exe),创建单文档应用程序,画一个弹簧(用矩形代替),下面挂有重物(用圆代替),设定重物质量和弹簧的弹性系数,模拟弹簧运动,可通过设置对话框来改变弹簧的一些基本参数,并实时绘制运动轨迹曲线图。
**源码链接:https://download.csdn.net/download/qq_46649692/16587973**
二、最终实现效果图
三、实现步骤(详细教程)
1、新建一个工程,取名“SpringSimulation”。
2、选择“单文档(S)”,点击“完成”,“确定”。
3、新建一个类
4、添加成员变量
5、构造函数里对变量初始化
代码如下
CTanHuang::CTanHuang()
{
m_YD.x = 200;
m_YD.y = 50;
m_kx = 200/0.2;
m_ky = -200/0.2;
m_K = 10.0;
m_L = 0.2;
m_l = 0.2;
m_m = 0.1;
m_Nv = 0;
m_Nl = 0;
m_v = 0.0;
}
6、添加成员函数Draw(CDC *p)
代码如下
void CTanHuang::Draw(CDC *p)
{
pDC = p;
int i;
int x,y,x1,y1;
int r = 20;
//画最上面悬挂弹簧的线
x = m_YD.x - 50;
y = m_YD.y;
pDC->MoveTo(x,y);
x = m_YD.x + 50;
pDC->LineTo(x,y);
x = m_YD.x;
y = m_YD.y;
pDC->MoveTo(x,y);
y = m_YD.y + 30;
pDC->LineTo(x,y);
//画弹簧
x = m_YD.x - 20;
x1 = m_YD.x + 20;
y1 = y - m_l * m_ky;
pDC->Rectangle(x,y,x1,y1);
//画弹簧与重物之间的线
x = m_YD.x;
y = y1;
pDC->MoveTo(x,y);
y += 20;
pDC->LineTo(x,y);
//画重物
y += r;
pDC->Ellipse(x-r,y-r,x+r,y+r);
//画曲线坐标轴
x = m_YD.x + 200;
y = m_YD.y;
pDC->MoveTo(x,y);
y += 300;
pDC->LineTo(x,y);
x += 300;
pDC->LineTo(x,y);
//画曲线
x = m_YD.x + 200;
y = m_YD.y + 300;
pDC->MoveTo(x,y);
for(i = 0; i < m_Nl; i++)
{
x = m_YD.x + 200 + 3 * i;
y = m_YD.y + 300 + m_nl[i] * m_ky;
pDC->LineTo(x,y);
}
//计算弹簧长度
m_nl[m_Nl] = m_l - m_L;
m_Nl++;
}
7、添加成员函数Move(float DeltaT)
代码如下
void CTanHuang::Move(float DeltaT)
{
float f,a,zn;
zn = 0.1 * fabs(m_v) * m_v;//记得嵌入#include "math.h"头文件
f = (m_l - m_L) * m_K - 9.8 * m_m - zn;
a = f/m_m;
m_v += a * DeltaT;
m_v *= 0.9;
m_l -= m_v * DeltaT;
}
8、设置菜单
鼠标单击“开始”,鼠标右击,选择“建立类向导…”,如下图所示。(“暂停”、“设置”操作同“开始”)
9、添加窗口消息句柄
10、引入#include "TanHuang.h"头文件
11、在OnTimer里调用
void CSpringSimulationView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
m_TanHuang.Move(0.1);
Invalidate(TRUE);
CView::OnTimer(nIDEvent);
}
12、在OnDraw里调用
void CSpringSimulationView::OnDraw(CDC* pDC)
{
CSpringSimulationDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
m_TanHuang.Draw(pDC);
}
13、在OnMStartSpring(),OnMPauseSpring() 里调用时钟函数
void CSpringSimulationView::OnMStartSpring()
{
// TODO: Add your command handler code here
SetTimer(1,100,NULL);
}
void CSpringSimulationView::OnMPauseSpring()
{
// TODO: Add your command handler code here
KillTimer(1);
}
14、编译运行初步效果图
15、新建对话框,设置弹簧参数
16、编辑对话框
17、建立类向导
18、添加成员变量
19、在OnMSetSpring()里传递对话框参数
代码如下
void CSpringSimulationView::OnMSetSpring()
{
// TODO: Add your command handler code here
CDlg_Set_Spring dlg;//记得引入#include "Dlg_Set_Spring.h"头文件
dlg.m_YD_X = m_TanHuang.m_YD.x;
dlg.m_YD_Y = m_TanHuang.m_YD.y;
dlg.m_L = m_TanHuang.m_L;
dlg.m_K = m_TanHuang.m_K;
dlg.m_m = m_TanHuang.m_m;
dlg.m_v = m_TanHuang.m_v;
UpdateData(FALSE);
if (dlg.DoModal() == IDOK)
{
m_TanHuang.m_YD.x = dlg.m_YD_X;
m_TanHuang.m_YD.y = dlg.m_YD_Y;
m_TanHuang.m_L = dlg.m_L;
m_TanHuang.m_K = dlg.m_K;
m_TanHuang.m_m = dlg.m_m;
m_TanHuang.m_v = dlg.m_v;
Invalidate(TRUE);
}
}
20、最终效果
可以通过对话框来设置一些基本参数。