VS2015平面四杆机构运动仿真编程

一、软件运行界面

二. 编程步骤

1. 新建MFC应用程序,项目名取为“FourBar”,在location中指定一个工作路径用于放置程序文件。

2. 在程序向导中选择建立一个“基于对话框”的应用程序,点击“下一步”直至结束向导。

3. 在对话框窗口布局控件。首先选中已有的静态文本“TODO:在这里设置对话框控件”,delete将其删除。从右侧控件工具栏中点击“Picture”图片控件,在对话框空白区域拖出一个矩形窗口,右键点击控件边框,弹出属性对话框,设定其控件的ID号:IDC_DISPLAY,Type属性为Rectangle,color为white,其余不变。再点击Group Box(成组框)控件,在对话框空白区域拖出一个矩形窗口,将其caption改为“输入四杆机构参数”,并在其中布置四个静态文本控件和四个编辑框控件,分别对应输入四杆机构的四个杆长尺寸。

为各个编辑框控件指定控件的ID号:

AB杆:IDC_AB;

BC杆:IDC_BC;

CD杆:IDC_CD;

AD杆:IDC_AD。

在成组框的下方添加2个按钮,其caption分别为“开始运动”和“停止运动”,其ID分别为IDC_START和IDC_STOP。将已有的“确定”按钮拖至下方并将其caption改为“退出”,并删除原有的“取消”按钮。这样对话框界面就设计好了,后续可以根据需要添加其他功能按钮等。

4. 为对话框中的控件添加相应的成员变量:点击菜单“项目 →类向导” 。

点击“Member Variables”标签项,依次选中对话框中的编辑控件IDC_AB、IDC_BC、IDC_CD、IDC_AD后点击“添加变量”,为添加对应的成员变量,类型为double,最小值0.0,最大值1000.0,如下图所示。

5. 四杆机构参数包括:各杆长尺寸ab,bc,cd,ad,曲柄位置角φ1、连杆位置角φ2、摇杆位置角φ3、机架倾角θ4。

直接在类向导,点击“Member Variables”标签项——“添加自定义”,为CFourBarDlg类中添加成员变量angle1,angle2,angle3,sita4,分别对应为AB、BC、CD、AD四杆的位置角,类型均设置为double。

6. 在CFourBarDlg类中添加成员函数DrawFourbar(),类型为void。将来在这个函数中实现四杆机构的参数计算及绘图。

7. 初始化四杆机构的参数:在CFourBarDlg类的OnInitDialog()函数中添加初始化代码:

// TODO: 在此添加额外的初始化代码

m_ab=100;

m_bc=250;

m_cd=200;

m_ad=200;

sita4=0;

angle1=45;

angle2=0;

angle3=0;

UpdateData(FALSE);  //将初始设定的杆长尺寸填入编辑框中显示

8. 在FourBarDlg.cpp前面加上科学计算的头文件,这样就可以支持三角函数的计算。

#include "stdafx.h"

#include "FourBar.h"

#include "FourBarDlg.h"

#include "afxdialogex.h"

#include "math.h"

9. 在CFourBarDlg类的函数DrawFourbar( )中添加语句,用来计算并画四杆机构图形。

void CFourBarDlg::DrawFourbar()

{

UpdateData(TRUE);

//获取对话框的图片控件的位置大小,并准备在其中绘图

CRect m_rect;

GetDlgItem(IDC_DISPLAY)->GetWindowRect(&m_rect);

ScreenToClient(&m_rect);

//获得绘图设备对象,并设置绘图区域大小,范围及原点

CClientDC dc(this);

dc.SetMapMode(MM_ISOTROPIC);

dc.SetWindowExt(CSize(500,500));

dc.SetViewportExt(m_rect.right,-m_rect.bottom);

dc.SetViewportOrg(m_rect.right/2,m_rect.bottom/2+50);

//当参数改变时重绘窗口

RedrawWindow(&m_rect);

//计算运动参数,此部分内容与《机械原理》教材计算方法完全一致。

double pi=3.1415926; // 定义圆周率π

double bx,by,cx,cy;  //铰链B、C点的坐标

double L, fai, aa, bb;  //定义中间变量

angle1=angle1*pi/180; //将角度值转化为弧度值

sita4=sita4*pi/180;

//计算辅助矢量BD的模与位置角

L = sqrt(m_ab * m_ab + m_ad * m_ad - 2 * m_ab * m_ad * cos(angle1 - sita4*pi/180));

fai = atan((m_ad * sin(sita4) - m_ab * sin(angle1)) / (m_ad * cos(sita4) - m_ab * cos(angle1)));

aa = (m_bc * m_bc - L * L - m_cd * m_cd) / (2 * L * m_cd);

angle3 = acos(aa) + fai;

bb = (L * sin(fai) + m_cd * sin(angle3)) / (L * cos(fai) + m_cd * cos(angle3));

angle2 = atan(bb);

if (bb < 0)

{

angle2 = angle2 + pi;

}

//计算B点和C点的坐标

bx = m_ab * cos(angle1);

by = m_ab * sin(angle1);

cx = bx + m_bc * cos(angle2);

cy = by + m_bc * sin(angle2);

//计算完成,下面设定画图需要的参数

CPen NewPen1;//声明画笔对象

CPen* pOldPen; //保存原先画笔的指针

//初始化实线、5像素宽的红色画笔

NewPen1.CreatePen(PS_SOLID,5,RGB(255,0,0));

//将画笔选入设备对象

pOldPen=dc.SelectObject(&NewPen1);

//画四杆机构,分成四个杆和对应的铰链进行绘制

//画AB杆

dc.MoveTo(0,0);

dc.LineTo(bx,by);

//画BC杆

dc.MoveTo(bx,by);

dc.LineTo(cx,cy);

dc.Ellipse(bx-10,by-10,bx+10,by+10);        //画转动副B

//画CD杆

dc.MoveTo(cx,cy);

dc.LineTo(m_ad,0);

dc.Ellipse(cx-10,cy-10,cx+10,cy+10);  //画转动副C

//画AD杆

dc.MoveTo(0,0);

dc.LineTo(m_ad,0);

dc.Ellipse(-10,-10,10,10);          //画转动副A

dc.Ellipse(m_ad-10,-10,m_ad+10,10);     //画转动副D

//画机架

for (int i=1;i<=12;i++)

{

dc.MoveTo((m_ad/12)*i,0);

dc.LineTo((m_ad/12)*i-20,-20);

}

dc.SelectObject(pOldPen); //恢复系统原来的画笔对象。

angle1=angle1*180/pi;  //将AB杆的位置角的弧度再转化为角度,准备后面用来递增。

}

10. 下面添加机构动画的功能。在类向导中选中“命令”,在Class name中选择“CFourBarDlg”类,目标ID号中选择“ID_START”,消息选择“BN_CLICKED”,添加处理程序,确认函数名为“OnStart”。同理,目标ID号中选择“ID_STOP”,消息选择“BN_CLICKED”,添加成员函数“OnStop”。分别在两个函数中设置定时器及撤销定时器。

分别添加程序如下:

void CFourBarDlg::OnStart()

{

// TODO: 在此添加控件通知处理程序代码

SetTimer(1, 100, NULL); //设置定时器

}

void CFourBarDlg::OnStop()

{

// TODO: 在此添加控件通知处理程序代码

KillTimer(1);   //删除定时器

} 11. 点击菜单“项目 →类向导”为菜单项命令添加消息映射函数。在Class name中选择“CFourBarDlg”类,在“Messages”中选择“WM_TIMER”,“添加处理程序”或双击,添加OnTimer成员函数。

12. 在OnTimer函数中添加如下代码:

void CFourBarDlg::OnTimer(UINT nIDEvent)

{

// TODO: Add your message handler code here and/or call default

if (angle1>360)

angle1=angle1-360;  //当曲柄转动角度大于360度时,重新从0度开始旋转。

angle1=angle1+2;  // 曲柄每次转动5度

DrawFourbar();  //调用四杆机构绘图函数

CDialog::OnTimer(nIDEvent);

}

13. 编译、连接,调试运行。

三、完整程序

// FourBarDlg.cpp : 实现文件

//

#include "stdafx.h"

#include "FourBar.h"

#include "FourBarDlg.h"

#include "afxdialogex.h"

#include "math.h"

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx

{

public:

CAboutDlg();

// 对话框数据

#ifdef AFX_DESIGN_TIME

enum { IDD = IDD_ABOUTBOX };

#endif

protected:

virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现

protected:

DECLARE_MESSAGE_MAP()

};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)

{

}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)

{

CDialogEx::DoDataExchange(pDX);

}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)

END_MESSAGE_MAP()

// CFourBarDlg 对话框

CFourBarDlg::CFourBarDlg(CWnd* pParent /*=NULL*/)

: CDialogEx(IDD_FOURBAR_DIALOG, pParent)

, m_ab(0)

, m_ad(0)

, m_bc(0)

, m_cd(0)

{

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);//自定义变量

angle1 = 0.0;

angle2 = 0.0;

angle3 = 0.0;

sita4 = 0.0;

}

void CFourBarDlg::DoDataExchange(CDataExchange* pDX)

{

CDialogEx::DoDataExchange(pDX);

DDX_Text(pDX, IDC_AB, m_ab);

DDX_Text(pDX, IDC_AD, m_ad);

DDX_Text(pDX, IDC_BC, m_bc);

DDX_Text(pDX, IDC_CD, m_cd);

}

BEGIN_MESSAGE_MAP(CFourBarDlg, CDialogEx)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

ON_BN_CLICKED(IDC_START, &CFourBarDlg::OnStart)

ON_BN_CLICKED(IDC_STOP, &CFourBarDlg::OnStop)

ON_WM_TIMER()

END_MESSAGE_MAP()

// CFourBarDlg 消息处理程序

BOOL CFourBarDlg::OnInitDialog()

{

CDialogEx::OnInitDialog();

// 将“关于...”菜单项添加到系统菜单中。

// IDM_ABOUTBOX 必须在系统命令范围内。

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu != NULL)

{

BOOL bNameValid;

CString strAboutMenu;

bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);

ASSERT(bNameValid);

if (!strAboutMenu.IsEmpty())

{

pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

}

}

// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动

//  执行此操作

SetIcon(m_hIcon, TRUE);                    // 设置大图标

SetIcon(m_hIcon, FALSE);            // 设置小图标

// TODO: 在此添加额外的初始化代码

m_ab = 100;

m_bc = 250;

m_cd = 200;

m_ad = 200;

sita4 = 0;

angle1 = 45;

angle2 = 0;

angle3 = 0;

UpdateData(FALSE);  //将初始设定的杆长尺寸填入编辑框中显示

return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE

}

void CFourBarDlg::OnSysCommand(UINT nID, LPARAM lParam)

{

if ((nID & 0xFFF0) == IDM_ABOUTBOX)

{

CAboutDlg dlgAbout;

dlgAbout.DoModal();

}

else

{

CDialogEx::OnSysCommand(nID, lParam);

}

}

// 如果向对话框添加最小化按钮,则需要下面的代码

//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,

//  这将由框架自动完成。

void CFourBarDlg::OnPaint()

{

if (IsIconic())

{

CPaintDC dc(this); // 用于绘制的设备上下文

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// 使图标在工作区矩形中居中

int cxIcon = GetSystemMetrics(SM_CXICON);

int cyIcon = GetSystemMetrics(SM_CYICON);

CRect rect;

GetClientRect(&rect);

int x = (rect.Width() - cxIcon + 1) / 2;

int y = (rect.Height() - cyIcon + 1) / 2;

// 绘制图标

dc.DrawIcon(x, y, m_hIcon);

}

else

{

CDialogEx::OnPaint();

}

}

//当用户拖动最小化窗口时系统调用此函数取得光标

//显示。

HCURSOR CFourBarDlg::OnQueryDragIcon()

{

return static_cast<HCURSOR>(m_hIcon);

}

void CFourBarDlg::DrawFourbar()

{

UpdateData(TRUE);

//获取对话框的图片控件的位置大小,并准备在其中绘图

CRect m_rect;

GetDlgItem(IDC_DISPLAY)->GetWindowRect(&m_rect);

ScreenToClient(&m_rect);

//获得绘图设备对象,并设置绘图区域大小,范围及原点

CClientDC dc(this);

dc.SetMapMode(MM_ISOTROPIC);

dc.SetWindowExt(CSize(500, 500));

dc.SetViewportExt(m_rect.right, -m_rect.bottom);

dc.SetViewportOrg(m_rect.right / 2, m_rect.bottom / 2 + 50);

//当参数改变时重绘窗口

RedrawWindow(&m_rect);

//计算运动参数,此部分内容与《机械原理》教材计算方法完全一致。

double pi = 3.1415926; // 定义圆周率π

double bx, by, cx, cy;  //铰链B、C点的坐标

double L, fai, aa, bb;  //定义中间变量

angle1 = angle1*pi / 180; //将角度值转化为弧度值

sita4 = sita4*pi / 180;

//计算辅助矢量BD的模与位置角

L = sqrt(m_ab * m_ab + m_ad * m_ad - 2 * m_ab * m_ad * cos(angle1 - sita4*pi / 180));

fai = atan((m_ad * sin(sita4) - m_ab * sin(angle1)) / (m_ad * cos(sita4) - m_ab * cos(angle1)));

aa = (m_bc * m_bc - L * L - m_cd * m_cd) / (2 * L * m_cd);

angle3 = acos(aa) + fai;

bb = (L * sin(fai) + m_cd * sin(angle3)) / (L * cos(fai) + m_cd * cos(angle3));

angle2 = atan(bb);

if (bb < 0)

{

angle2 = angle2 + pi;

}

//计算B点和C点的坐标

bx = m_ab * cos(angle1);

by = m_ab * sin(angle1);

cx = bx + m_bc * cos(angle2);

cy = by + m_bc * sin(angle2);

//计算完成,下面设定画图需要的参数

CPen NewPen1;//声明画笔对象

CPen* pOldPen; //保存原先画笔的指针

//初始化实线、5像素宽的红色画笔

NewPen1.CreatePen(PS_SOLID, 5, RGB(255, 0, 0));

//将画笔选入设备对象

pOldPen = dc.SelectObject(&NewPen1);

//画四杆机构,分成四个杆和对应的铰链进行绘制

//画AB杆

dc.MoveTo(0, 0);

dc.LineTo(bx, by);

//画BC杆

dc.MoveTo(bx, by);

dc.LineTo(cx, cy);

dc.Ellipse(bx - 10, by - 10, bx + 10, by + 10);    //画转动副B

//画CD杆

dc.MoveTo(cx, cy);

dc.LineTo(m_ad, 0);

dc.Ellipse(cx - 10, cy - 10, cx + 10, cy + 10);  //画转动副C

//画AD杆

dc.MoveTo(0, 0);

dc.LineTo(m_ad, 0);

dc.Ellipse(-10, -10, 10, 10);          //画转动副A

dc.Ellipse(m_ad - 10, -10, m_ad + 10, 10);     //画转动副D

//画机架

for (int i = 1; i <= 12; i++)

{

dc.MoveTo((m_ad / 12)*i, 0);

dc.LineTo((m_ad / 12)*i - 20, -20);

}

dc.SelectObject(pOldPen); //恢复系统原来的画笔对象。

angle1 = angle1 * 180 / pi;  //将AB杆的位置角的弧度再转化为角度,准备后面用来递增。

}

void CFourBarDlg::OnStart()

{

// TODO: 在此添加控件通知处理程序代码

SetTimer(1, 100, NULL); //设置定时器

}

void CFourBarDlg::OnStop()

{

// TODO: 在此添加控件通知处理程序代码

KillTimer(1);   //删除定时器

}

void CFourBarDlg::OnTimer(UINT_PTR nIDEvent)

{

// TODO: 在此添加消息处理程序代码和/或调用默认值

if (angle1>360)

angle1 = angle1 - 360;  //当曲柄转动角度大于360度时,重新从0度开始旋转。

angle1 = angle1 + 2;  // 曲柄每次转动5度

DrawFourbar();  //调用四杆机构绘图函数

CDialogEx::OnTimer(nIDEvent);

}

VS2015平面四杆机构运动仿真编程相关推荐

  1. 物体运动到一个点停止_运用SolidWorks运动仿真来做的最速降线及其验证,来看看我的办法...

    一个仅受重力的物体,从一个点出发,沿着一条没有摩擦的斜坡滚动到另外一个点.肯定有一个斜坡使物体运动的时间最短.这个斜坡所在的曲线就是"最速降线". 关于这个最速降线是怎么计算出来, ...

  2. abb机器人焊接编程视频教程_智能制造仿真编程之带导轨的ABB机器人

    智能制造仿真编程之带导轨的ABB机器人 作为机器人四大家族之一的ABB机器人以其领先的技术和良好的质量闻名于世,在ABB机器人手册中提供了大量的可选项功能.例行程序和设备型号帮助工程师减少工作量,提升 ...

  3. matlab平行因子_基于MATLAB某客车悬置系统优化与运动仿真

    本文对一CNG燃气客车悬置系统建立6阶振动数学模型,基于MATLAB分析振动频率与解耦率并对系统固有频率的配置以及解耦率设计优化程序,运用NX CAE运动仿真校核MATLAB分析结果的准确性,为悬置系 ...

  4. matlab中画出3d船舶,船舶运动仿真中航迹与船形图的应用(上)

    船舶运动仿真中航迹与船形图的应用(上) 在船舶运动控制领域,数字仿真是较为通用的研究手段.为什么?这与问题的复杂性不无关系.我们知道,对航行在气象条件多变的海洋环境下的船舶动态进行较深入的研究,并且要 ...

  5. 02论文分享与分析——基于ROS的移动机械臂底层规划及运动仿真

    [1]钱伟. 基于ROS的移动操作机械臂底层规划及运动仿真[D].哈尔滨工业大学,2015. 0.摘要 钱伟学长的论文在我学习轨迹规划初期就开始阅读,在学习过程中,也对于很多疑惑的问题,找寻到了答案, ...

  6. JAVA中的多线程与运动仿真(1)——用JAVA来放一场烟花

    JAVA中的多线程与运动仿真(1)--用JAVA来放一场烟花 一.实现效果的简单展示: 初步实现的动态效果为在鼠标点击之后,点击之处出现一簇小球,然后向不同方向散开变大. 利用这一效果,再在后续增加颜 ...

  7. 灌装机的灌装结构设计及仿真(lunwen+任务书+开题+文综+翻译及原文+答辩PPT+cad图纸+UG模型及运动仿真)

    目 录 摘 要 I Abstract II 第1章 绪论 1 1.1选题背景及意义 1 1.2国内外发展现状 2 1.3研究主要内容 3 第2章 灌装机的灌装结构方案设计 5 2.1工作原理及工艺过程 ...

  8. 落地扇的三维造型与运动仿真

    目 录 摘 要 I Abstract II 目 录 III 1 绪论 1 1.1 选题背景及意义 1 1.2研究现状 1 1.4 研究主要内容 2 2 基于UG的落地扇造型设计 4 2.1 设计思路 ...

  9. python运动仿真_硬核推导火箭运动方程,并用python仿真实现

    作者:yangjian 1 坐标系变换 火箭的运动方程是基于牛顿运动学方程推导,牛顿运动学方程是在惯性坐标系下成立的,目标的运动必须以固定的惯性坐标系为参考.本文研究带尾翼控制的火箭,火箭主要是由火箭 ...

最新文章

  1. C++中的volatile关键字
  2. linux内存之buff/cache
  3. php和python和java-python和java,php,c,c#,c++的对比
  4. idea设置启动时打开欢迎页
  5. android上滑隐藏动画,ListView上滑和下滑,显示和隐藏Toolbar的实现方法
  6. 常见的ORACLE锁模式汇总
  7. 服务器的类型及作用是什么,按用途分类,服务器有哪些? - 问答库
  8. C++map容器应用举例
  9. Pytorch:保存图片
  10. 3招seo技巧让你把关键词做进百度前三
  11. Spring DataSource JNDI - Tomcat JNDI 配置示例
  12. 修改oracle 的dbname,在oracle 10g上修改dbname的实验
  13. 分布式 和 集群的区别
  14. 基于编辑方法的文本生成(上)
  15. Altium design 的smart pdf 打印不出汉字来。
  16. FastStone Capture 下载
  17. 大局观有多重要?如何拥有大局观?
  18. char可以存储汉字吗?为什么
  19. 南下打工潮正在远去!去年千万人返乡,农业的大转折正在到来
  20. 小时 分钟 秒 计算

热门文章

  1. IntelliJ IDEA修改项目名字
  2. 读陈景润之《初等数论》
  3. 恒星物联-排水管网有害气体监测系统 有害气体监测
  4. 华大超低功耗单片机-样片、开发板快速免费申请方法
  5. Android P中的AVB校验(一)
  6. MATLAB下实现巴特沃斯低通滤波器并对图像滤波
  7. 电控无碳小车需要单片机吗_智能避障无碳小车-精选文档
  8. 读秀数据库的用法+全国图书馆参考咨询联盟
  9. Linux系统文件默认权限
  10. 解决ubuntu没有声音的问题