MFC飞剪机构运动仿真

软件运行界面

代码区



#include "pch.h"
#include "framework.h"
#include "Flyingshear.h"
#include "FlyingshearDlg.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()


// CFlyingshearDlg 对话框



CFlyingshearDlg::CFlyingshearDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_FLYINGSHEAR_DIALOG, pParent)
	, m_a(0)
	, m_b(0)
	, m_c(0)
	, m_d(0)
	, m_e(0)
	, m_f(0)
	, fai1(0)
    , alpha2(0)
	, alpha3(0)
	, alpha4(0)
	, Jdbc(0)
	, Jdbx(0)
	, Jbdc(0) 
	, Jbdy(0)
	, J2(0)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	
}

void CFlyingshearDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_A, m_a);
	DDV_MinMaxDouble(pDX, m_a, 0.0, 1500.0);
	DDX_Text(pDX, IDC_B, m_b);
	DDV_MinMaxDouble(pDX, m_b, 0.0, 1500.0);
	DDX_Text(pDX, IDC_C, m_c);
	DDV_MinMaxDouble(pDX, m_c, 0.0, 1500.0);
	DDX_Text(pDX, IDC_D, m_d);
	DDV_MinMaxDouble(pDX, m_d, 0.0, 1500.0);
	DDX_Text(pDX, IDC_E, m_e);
	DDV_MinMaxDouble(pDX, m_e, 0.0, 1500.0);
	DDX_Text(pDX, IDC_F, m_f);
	DDV_MinMaxDouble(pDX, m_f, 0.0, 1500.0);
}

BEGIN_MESSAGE_MAP(CFlyingshearDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_START, &CFlyingshearDlg::OnStart)
	ON_BN_CLICKED(IDC_STOP, &CFlyingshearDlg::OnStop)
	ON_WM_TIMER()
END_MESSAGE_MAP()


// CFlyingshearDlg 消息处理程序

BOOL CFlyingshearDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

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

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		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_a = 193.455;
	m_b = 464.1927;
	m_c = 1275.683;
	m_d = 1241.519;
	m_e = 470.709;
	m_f = 845.0333;
	//弧度
	fai1 = 0;
	xA = 0;
	yA = 0;
	xD = 221.8746104;
	yD = 111.4738172;
	xAD = 1109.37;
	yAD = 557.369;
	//alpha2 = 160.1443;
	//alpha3 = 46.15824;
	//alpha4 = 26.67578;
	alpha2 = 2.795046;
	alpha3 = 0.805613;
	alpha4 = 0.46558;
	pi = 3.1415926;
	UpdateData(FALSE);  //将初始设定的杆长尺寸填入编辑框中显示
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CFlyingshearDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CFlyingshearDlg::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 CFlyingshearDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CFlyingshearDlg::DrawFlyingBar()
{
	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 xE, yE, xF, yF, xB, yB, xC, yC, xBD, yBD, LBD;
	
	//fai1 = fai1 * pi / 180;
	//alpha2 = alpha2 * pi / 180;
	//alpha3 = alpha3 * pi / 180;
	//alpha4 = alpha4 * pi / 180;

	xB = (m_a * cos(fai1)) / 5;
	yB = (m_a * sin(fai1)) / 5;

	xBD = xAD - m_a * cos(fai1);
	yBD = yAD - m_a * sin(fai1);
	Jdbx = atan(yBD / xBD);
	LBD = yBD / sin(Jdbx);
	Jdbc = acos(((LBD * LBD) + (m_b * m_b) - (m_c * m_c)) / (2 * LBD * m_b));
	Jbdc = acos(((LBD * LBD) + (m_c * m_c) - (m_b * m_b)) / (2 * LBD * m_c));
	Jbdy = atan(xBD / yBD);
	J2 = 2 * pi - (Jdbc - Jdbx);
	
	xC = xB + (m_b * cos(J2)) / 5;
	yC = yB + (m_b * sin(J2)) / 5;

	xE = xB + (m_e * cos(alpha2 - Jdbc + Jdbx)) / 5;
	yE = yB + (m_e * sin(alpha2 - Jdbc + Jdbx)) / 5;

	xF = xD + (m_f * cos(pi*1.5 - alpha3 - Jbdy + Jbdc)) / 5;
	yF = yD + (m_f * sin(pi*1.5 - alpha3 - Jbdy + Jbdc)) / 5;

	//double fai, fai2, fai3, l;
	//l = sqrt(pow(m_a, 2) + pow(m_d, 2) - 2 * m_a * m_d * cos(fai1 - alpha4));
	//fai = atan((m_d * sin(alpha4) - m_a * sin(fai1)) / (m_d * cos(alpha4) - m_a * cos(fai1)));
	//if (fai < 0)
	//{
	//	fai = pi + fai;
	//}
	//fai3 = fai - acos((pow(m_b, 2) - pow(l, 2) - pow(m_c, 2)) / (2 * l * m_c));
	//if ((l * cos(fai) + m_c * cos(fai3)) < 0)
	//{
	//	fai2 = atan(-(l * sin(fai) + m_c * sin(fai3)) / (l * cos(fai) + m_c * cos(fai3)));
	//}
	//else
	//{
	//	fai2 = atan((l * sin(fai) + m_c * sin(fai3)) / (l * cos(fai) + m_c * cos(fai3)));
	//}
	//xE = (m_a * cos(fai1) + m_e * cos(fai2 + alpha2))/5;
	//xF = (xD + m_f * cos(fai3 - alpha3))/5;
	//yE = (m_a * sin(fai1) + m_e * sin(fai2 + alpha2))/5;
	//yF = (yD + m_f * sin(fai3 - alpha3))/5;

	//设定画图需要的参数       
	CPen NewPen1;//声明画笔对象
	CPen* pOldPen; //保存原先画笔的指针
	//初始化实线、5像素宽的红色画笔
	NewPen1.CreatePen(PS_SOLID, 5, RGB(255, 0, 0));
	//将画笔选入设备对象
	pOldPen = dc.SelectObject(&NewPen1);

	//A点转动副
	dc.Ellipse(yA - 10, xA - 10, yA + 10, xA + 10);
	//画AB杆
	dc.MoveTo(yA, xA);
	dc.LineTo(yB, xB);
	//画BC杆
	dc.MoveTo(yB, xB);
	dc.LineTo(yC, xC);
	//画转动副B
	dc.Ellipse(yB - 10, xB - 10, yB + 10, xB + 10);  
	//画转动副C
	dc.Ellipse(yC - 10, xC - 10, yC + 10, xC + 10);
	//画转动副D
	dc.Ellipse(yD - 10, xD - 10, yD + 10, xD + 10);
	//画CD杆
	dc.MoveTo(yD, xD);
	dc.LineTo(yC, xC);

	//画DF杆
	dc.MoveTo(yD, xD);
	dc.LineTo(yF, xF);
	//画BE杆
	dc.MoveTo(yB, xB);
	dc.LineTo(yE, xE);

	dc.SelectObject(pOldPen); //恢复系统原来的画笔对象。
	//fai1 = fai1 * 180 / pi;  //将AB杆的位置角的弧度再转化为角度,准备后面用来递增。
}


void CFlyingshearDlg::OnStart()
{
	// TODO: 在此添加控件通知处理程序代码
	SetTimer(1, 100, NULL); //设置定时器
}


void CFlyingshearDlg::OnStop()
{
	// TODO: 在此添加控件通知处理程序代码
	KillTimer(1);   //删除定时器
}


void CFlyingshearDlg::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (fai1 > 2*pi)
	{
		fai1 = fai1 - 2 * pi; //当转动角度大于360度时,重新从0度开始旋转。
	}
	fai1 = fai1 + 0.1;  
	DrawFlyingBar();  //调用飞剪机构绘图函数
	CDialog::OnTimer(nIDEvent);
	CDialogEx::OnTimer(nIDEvent);
}

``注意的是,不变量一定要设置成员变量进行初始化,我开始做的时候有些变量没有初始化,就老是不对,查不出错,后面改了才对,还要角度和弧度的设置,我试了好多次才找到错误,一定要注意

我也初学者,希望大佬批评指正

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值