升级版飞剪机构仿真
// FlyshearDlg.cpp: 实现文件
//
#include "pch.h"
#include "framework.h"
#include "Flyshear.h"
#include "FlyshearDlg.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()
// CFlyshearDlg 对话框
CFlyshearDlg::CFlyshearDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_FLYSHEAR_DIALOG, pParent)
, m_k(0)
, m_gamma2(0)
, m_psi(0)
, m_alpha4(0)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
pi = 0.0;
fai1 = 0.0;
xA = 0.0;
yA = 0.0;
xD = 0.0;
yD = 0.0;
xAD = 0.0;
yAD = 0.0;
Jdbc = 0.0;
Jdbx = 0.0;
Jbdy = 0.0;
Jbdc = 0.0;
J2 = 0.0;
xE0[0] = 44.95301;
yE0[0] = 93.9331;
xF0[0] = 53.70745;
yF0[0] = 94.64961;
n = 0;
}
void CFlyshearDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_K, m_k);
DDV_MinMaxDouble(pDX, m_k, 1.0, 2.0);
DDX_Text(pDX, IDC_GAMMA2, m_gamma2);
DDV_MinMaxDouble(pDX, m_gamma2, 0.0, 3.1415926);
DDX_Text(pDX, IDC_PSI, m_psi);
DDV_MinMaxDouble(pDX, m_psi, 0.0, 3.1415926);
DDX_Text(pDX, IDC_ALPHA4, m_alpha4);
DDV_MinMaxDouble(pDX, m_alpha4, 0.0, 3.1415926);
}
BEGIN_MESSAGE_MAP(CFlyshearDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_START, &CFlyshearDlg::OnStart)
ON_BN_CLICKED(IDC_STOP, &CFlyshearDlg::OnStop)
ON_WM_TIMER()
END_MESSAGE_MAP()
// CFlyshearDlg 消息处理程序
BOOL CFlyshearDlg::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_alpha4 = 0.453785598;
m_gamma2 = 1.25663704;
m_k = 1.16;
m_psi = 0.31415926;
fai1 = 0;
xA = 0;
yA = 0;
xE0[1] = 44.95301;
yE0[1] = 93.9331;
xF0[1] = 53.70745;
yF0[1] = 94.64961;
n = 0;
UpdateData(FALSE);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CFlyshearDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CFlyshearDlg::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 CFlyshearDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CFlyshearDlg::DrawFlyShear()
{
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+250, m_rect.bottom / 2 - 60);
//当参数改变时重绘窗口
RedrawWindow(&m_rect);
// TODO: 在此处添加实现代码.
pi = 3.1415926;
double theta, theta0, gamma1, A, B, N, a0, b0, c0;
theta = pi * (m_k - 1) / (m_k + 1);
gamma1 = m_psi + m_gamma2 - theta;
theta0 = atan((sin(m_gamma2) * sin(theta)) / (sin(gamma1) - sin(m_gamma2) * cos(theta)));
A = cos(theta + theta0) * sin(m_gamma2 + theta0);
B = sin(m_gamma2) + sin(theta0) * cos(gamma1 + theta + theta0);
N = 2 * sin(m_gamma2) * cos(theta + theta0);
a0 = (A - B) / N;
b0 = (A + B) / N;
c0 = sin(theta0) / sin(m_gamma2);
int L = 1, t;
double Vt = 2, delta = 1.02, k1 = 1.1, n1, omega1, a, b, c, d, mu_L;
t = L / Vt;
n1 = 60 * Vt / L;
omega1 = 2 * pi * Vt / L;
a = k1 * delta * L / (2 * pi);
mu_L = a / a0;
b = mu_L * b0;
c = mu_L * c0;
d = mu_L;
int h = 250, deta_h = 5, deta_b = 1;
double f, e, deta_alpha, alpha3, Lce, Lcf, alpha2, Lcef, alpha2_x, alpha3_x;
f = 1000 * d * cos(m_alpha4) - h;//乘1000是为了单位转换
e = sqrt(pow((f - deta_h),2) + pow(((d*1000) - (a*1000)),2) - 2 * (f - deta_h) * ((d*1000) - (a*1000)) * cos(m_alpha4));
deta_alpha = acos((pow(c,2) + pow((d - a),2) - pow(b,2)) / (2 * c * (d - a)));
alpha3 = deta_alpha + m_alpha4;
Lce = sqrt(pow((c*1000),2) + pow((f - deta_h),2) - 2 * (c*1000) * (f - deta_h) * cos(alpha3));
Lcf = sqrt(pow((c*1000),2) + pow(f,2) - 2 * (c*1000) * (f)*cos(alpha3));
Lcef = (Lce + Lcf) / 2;
alpha2_x = acos((pow((b*1000),2) + pow(e,2) - pow(Lcef,2)) / (2 * (b*1000) * e));
alpha3_x = acos((pow((c*1000),2) + pow(f,2) - pow(Lcef,2)) / (2 * (c*1000) * f));
double Jbec, Jdec, Jbed, Jdab, Lbd, fai10;
Jbec = acos((pow(e,2) + pow(Lcef,2) - pow((b*1000),2)) / (2 * e * Lcef));
Jdec = acos((pow(f,2) + pow(Lcef,2) - pow((c*1000),2)) / (2 * f * Lcef));
Jbed = Jbec + Jdec;
Lbd = sqrt(pow(e,2) + pow(f,2) - 2 * e * f * cos(Jbed));
Jdab = acos((pow((a*1000),2) + pow((d*1000),2) - pow(Lbd,2)) / (2 * (a*1000) * (d*1000)));
fai10 = m_alpha4 - Jdab;
double faii, fai3, fai2, faiE, deta_faiE, alpha4_x, fai10_x, fai2_x, fai3_x;
faii = atan((d * sin(m_alpha4) - a * sin(fai10)) / (d * cos(m_alpha4) - a * cos(fai10)));
fai3 = faii + (2*pi - acos((pow((b*1000),2) - pow(Lbd,2) - pow((c*1000),2)) / (2 * Lbd * (c*1000))));
fai2 = atan((Lbd * sin(faii) + (c*1000) * sin(fai3)) / (Lbd * cos(faii) + (c*1000) * cos(fai3)));
faiE = atan((e * sin(fai2 + alpha2_x) - (b*1000) * sin(fai2)) / (e * cos(fai2 + alpha2_x) - (b*1000) * cos(fai2)));
deta_faiE = faiE - pi/2;
alpha4_x = m_alpha4 - deta_faiE;
fai10_x = fai10 - deta_faiE;
fai2_x = fai2 - deta_faiE;
fai3_x = fai3 - deta_faiE;
double omega2, omega3, VEt, VFt, Vdao, detlai, k1_x, a_x, mu_x, b_x, c_x, d_x, e_x, f_x;
omega2 = (-(a*1000) * omega1 * sin(fai10_x - fai3_x)) / ((b*1000) * sin(fai2_x - fai3_x));
omega3 = ((a*1000) * omega1 * sin(fai10_x - fai2_x)) / ((c*1000) * sin(fai3_x - fai2_x));
VEt = (a*1000) * omega1 * cos(fai10_x) + e * omega2 * cos(fai2_x + alpha2_x);
VFt = f * omega3 * cos(fai3_x - alpha3_x);
Vdao = (VEt + VFt) / 2;
detlai = Vdao / Vt;
k1_x = (a*1000) * omega1 / Vdao;
a_x = (k1_x * delta * Vt / omega1) * 1000;
mu_x = a_x / (a * 1000);
b_x = 1000 * (mu_x * b);
c_x = 1000 * (mu_x * c);
d_x = 1000 * (mu_x * d);
f_x = mu_x * f;
e_x = mu_x * e;
double xE, yE, xF, yF, xB, yB, xC, yC, xBD, yBD, LBD;
xD = (d_x * cos(alpha4_x)) / 5;
yD = (d_x * sin(alpha4_x)) / 5;
xAD = d_x * cos(alpha4_x);
yAD = d_x * sin(alpha4_x);
xB = (a_x * cos(fai1)) / 5;
yB = (a_x * sin(fai1)) / 5;
xBD = xAD - a_x * cos(fai1);
yBD = yAD - a_x * sin(fai1);
Jdbx = atan(yBD / xBD);
LBD = yBD / sin(Jdbx);
Jdbc = acos(((LBD * LBD) + (b_x * b_x) - (c_x * c_x)) / (2 * LBD * b_x));
Jbdc = acos(((LBD * LBD) + (c_x * c_x) - (b_x * b_x)) / (2 * LBD * c_x));
Jbdy = atan(xBD / yBD);
J2 = 2 * pi - (Jdbc - Jdbx);
xC = xB + (b_x * cos(J2)) / 5;
yC = yB + (b_x * sin(J2)) / 5;
xE = xB + (e_x * cos(alpha2_x - Jdbc + Jdbx)) / 5;
yE = yB + (e_x * sin(alpha2_x - Jdbc + Jdbx)) / 5;
xF = xD + (f_x * cos(pi * 1.5 - alpha3_x - Jbdy + Jbdc)) / 5;
yF = yD + (f_x * sin(pi * 1.5 - alpha3_x - Jbdy + Jbdc)) / 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);
//画机架
CPoint pD[3] = { CPoint(yD,xD), CPoint(yD + 20,xD + 34.641016), CPoint(yD - 20,xD + 34.641016) };
dc.Polygon(pD, 3);
CPoint pA[3] = { CPoint(yA,xA), CPoint(yA - 20,xA - 34.641016), CPoint(yA + 20,xA - 34.641016) };
dc.Polygon(pA, 3);
//画DF杆
dc.MoveTo(yD, xD);
dc.LineTo(yF, xF);
//画BE杆
dc.MoveTo(yB, xB);
dc.LineTo(yE, xE);
dc.SelectObject(pOldPen); //恢复系统原来的画笔对象。
//设定画图需要的参数
CPen NewPen2;//声明画笔对象
CPen* pOldPen1; //保存原先画笔的指针
//初始化实线、5像素宽的红色画笔
NewPen2.CreatePen(PS_SOLID, 5, RGB(0, 0, 255));
//将画笔选入设备对象
pOldPen1 = dc.SelectObject(&NewPen2);
if (n != 0)
{
xE0[n] = xE;
yE0[n] = yE;
xF0[n] = xF;
yF0[n] = yF;
if (n > 63)
{
n = n - 63;
}
for (int i = n; i > 0; i--)
{
//E点的轨迹
dc.MoveTo(yE0[i], xE0[i]);
dc.LineTo(yE0[i - 1], xE0[i - 1]);
//F点的轨迹
dc.MoveTo(yF0[i], xF0[i]);
dc.LineTo(yF0[i - 1], xF0[i - 1]);
}
}
n++;
dc.SelectObject(pOldPen1); //恢复系统原来的画笔对象。
}
void CFlyshearDlg::OnStart()
{
// TODO: 在此添加控件通知处理程序代码
SetTimer(1, 100, NULL); //设置定时器
}
void CFlyshearDlg::OnStop()
{
// TODO: 在此添加控件通知处理程序代码
KillTimer(1); //删除定时器
}
void CFlyshearDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (fai1 > 2 * pi)
{
fai1 = fai1 - 2 * pi; //当转动角度大于360度时,重新从0度开始旋转。
}
fai1 = fai1 + 0.1;
DrawFlyShear(); //调用飞剪机构绘图函数
CDialog::OnTimer(nIDEvent);
CDialogEx::OnTimer(nIDEvent);
}
欢迎大家批评指正
版权所属YW
下载地址
添加链接描述