
两跨连续梁影响线绘制-附源码
一、题目描述
1.用户输入L1和L2的值,求D点弯矩影响线;
2.车辆在此连续梁上前后任意移动,求出车辆对D点产生的弯矩最大效应系数。
二、效果

三、代码实现
CCalculation.cpp
#include "stdafx.h" #include "CCalculation.h" #include CCalculation::CCalculation(void) { } CCalculation::CCalculation(const double l1,const double l2) :m_dL1(l1),m_dL2(l2) { } CCalculation::CCalculation(const double l1,const double l2,const double l3) :m_dL1(l1),m_dL2(l2),m_dL3(l3) { } CCalculation::~CCalculation(void) { } void CCalculation::Initlize(void) { m_dL1 = 100; m_dL2 = 100; m_dL3 = 3; } double CCalculation::GetInfluenceY(const double x) const { double dL1=GetSpanL1(); double dL2=GetSpanL2(); double dL=GetLength(); double dResult = 0; assert(x>=0); //单位力Fp从右向左移动 if (x>=0 && x<=dL2/2.0) //第二跨(右) { dResult = ((pow(x,3)+xpow(dL2,2))/dL2+2.0dL1x)/(4.0(dL1+dL2)); return dResult; } else if(x>dL2/2.0 && x<=dL2) //第二跨(左) { dResult = (pow(dL2-x,2)(x+2dL2)/dL2+2.0dL1(dL2-x))/(4.0(dL1+dL2)); return dResult; } else //if(x>dL2 && x<=dL)//第一跨 { //使用力法计算拐点弯矩M1和M2 double dDelta1=(2.0dL1+dL2)/6.0; double dY1=(dL1+dL2-x)/dL1; double dY2=(dL1+dL2-x)(x-dL2)/dL1; double dP=(dL1+dL2-x)dY2dY1/3.0+(x-dL2)dY2(2.0dY1/3.0+1.0/3.0)/2.0; double dM1=-dP/dDelta1; double dM2=dY1dM1+dY2; //计算影响线 double a=2.0(dL1+dL2-x)/dL1; double dDelta2=4.0(dL1+dL2)/3.0; double dP1 = (dL1+dL2-x)dM2a/3.0; double dP2 = (x-dL2)*(2.0dM2a+4.0dM1+2.0dM2+dM1a)/6.0; double dP3 = 5.0*dM1/12.0; double dp = dP1 + dP2 + dP3; dResult = -dp/dDelta2; return dResult; } } //计算效应系数 double CCalculation::GetEffectCoeffient() const { double dInfluenceLineMaxY = 0; double dAllLength = GetLength(); double dLength1 = GetSpanL1(); double dLength2 = GetSpanL2(); double dLength3 = GetSpanL3(); double dTempY = 0; CPoint MaxPoint(0,0); //找到最大效用系数 for (int i = 0;i <= dAllLength; i++) //车辆从右向左运行 { dTempY = GetInfluenceY(i); if (abs(dTempY) > abs(dInfluenceLineMaxY)) { dInfluenceLineMaxY = dTempY; MaxPoint.x = i; MaxPoint.y = (int)dInfluenceLineMaxY; } } CPoint MaxPoint2(0,0); if (MaxPoint.x < dLength2) //若最大点在BC跨 { MaxPoint2.x = MaxPoint.x + (int)dLength3; MaxPoint2.y = (int)GetInfluenceY(MaxPoint2.x); } else //若最大点在AB跨 { MaxPoint2.x = MaxPoint.x - (int)dLength3; MaxPoint2.y = (int)GetInfluenceY(MaxPoint2.x); } return abs(MaxPoint.y + MaxPoint2.y); } double CCalculation::GetSpanL1() const { return m_dL1; } double CCalculation::GetSpanL2() const { return m_dL2; } double CCalculation::GetSpanL3() const { return m_dL3; } double CCalculation::GetLength() const { return m_dL1+m_dL2; }
CDrawLine.cpp
#include "stdafx.h" #include "CDrawLine.h" #include “resource.h” #include “CCalculation.h” #include “InfluenceLineDlg.h” CDrawLine::CDrawLine(void) { } CDrawLine::~CDrawLine(void) { } void CDrawLine::DrawInfulenceLine(CWnd *pWnd,double dLength1,double dLength2) const { CRect rect; pWnd->GetClientRect(&rect); CDC *pDC = pWnd->GetDC(); pWnd->Invalidate(); pWnd->UpdateWindow(); //将背景颜色为白色 CBrush newBrush; CBrush *pOldBrush; newBrush.CreateSolidBrush(RGB(255,255,255)); pOldBrush = pDC->SelectObject(&newBrush); pDC->Rectangle(rect); pDC->SelectObject(pOldBrush); newBrush.DeleteObject(); //创建黑色画笔 CPen newPen; CPen *pOldPen; newPen.CreatePen(PS_SOLID, 2, RGB(0,0,0)); pOldPen = pDC->SelectObject(&newPen); CCalculation Cal(dLength1,dLength2); double dL = Cal.GetLength(); double dL1 = Cal.GetSpanL1(); double dL2 = Cal.GetSpanL2(); int nWidth = rect.Width(); int nHeight = rect.Height(); //绘制横轴 CPoint StartPt(nWidth/10,nHeight/2); CPoint EndPt(9*nWidth/10,nHeight/2); pDC->MoveTo(StartPt); pDC->LineTo(EndPt); //绘制三角形支座 CPoint Pt1[4]; Pt1[0] = StartPt; Pt1[1] = CPoint(StartPt.x-12, StartPt.y+20); Pt1[2] = CPoint(StartPt.x+12, StartPt.y+20); Pt1[3] = StartPt; pDC->Polyline(Pt1, 4); CPoint MiddlePt(nWidth/10+(int)(dL1*(8*nWidth/10)/dL), nHeight/2); CPoint Pt2[4]; Pt2[0] = MiddlePt; Pt2[1] = CPoint(MiddlePt.x-12, MiddlePt.y+20); Pt2[2] = CPoint(MiddlePt.x+12, MiddlePt.y+20); Pt2[3] = MiddlePt; pDC->Polyline(Pt2, 4); CPoint Pt3[4]; Pt3[0] = EndPt; Pt3[1] = CPoint(EndPt.x-12, EndPt.y+20); Pt3[2] = CPoint(EndPt.x+12, EndPt.y+20); Pt3[3] = EndPt; pDC->Polyline(Pt3, 4); //在图中输出支座编号A、B、C pDC->TextOut(StartPt.x,StartPt.y+25,_T("A")); pDC->TextOut(MiddlePt.x,MiddlePt.y+25,_T("B")); pDC->TextOut(EndPt.x,EndPt.y+25,_T("C")); pDC->TextOut((MiddlePt.x+EndPt.x-MiddlePt.x)/2,MiddlePt.y+25,_T("D")); //在图中输出跨度编号L1、L2 pDC->TextOut(StartPt.x+(MiddlePt.x+StartPt.x)/2,StartPt.y-25,_T("L1")); pDC->TextOut(MiddlePt.x+(EndPt.x+MiddlePt.x)/2,StartPt.y-25,_T("L2")); //绘制影响线 int nX=0; int nY=0; int nTemp = 0; double dResultY = 0; CPoint CoorMaxDraw(0,nHeight/2); //记录BC跨影响线最大值的图形坐标点 CPoint CoorMaxReal(0,0); //记录BC跨影响线最大值的计算真实值 /*CPoint CoorMinDraw(0,nHeight/2); //记录AB跨影响线最大值的图形坐标点 CPoint CoorMinReal(0,0); //记录AB跨影响线最大值的计算真实值*/ for (int i = 0;i <=(int)dL; i++) { nTemp = (int)dL - i; nX=nWidth/10+(nTemp*8*nWidth/10)/(int)dL; dResultY = Cal.GetInfluenceY(i); nY=(int)((double)nHeight/2 - dResultY*5.0); pDC->LineTo(nX,nY); //记录BC跨影响线最大点 int nTempY = -(nY-nHeight/2); int nTempDrawMaxY = -(CoorMaxDraw.y -nHeight/2); if (nTempY >= nTempDrawMaxY) { CoorMaxDraw.x = nX; CoorMaxDraw.y = nY; CoorMaxReal.x = i; CoorMaxReal.y = (int)dResultY; } //记录AB跨影响线最大点 /*int nTempDrawMinY = -(CoorMinDraw.y -nHeight/2); if (nTempY < nTempDrawMinY) { CoorMinDraw.x = nX; CoorMinDraw.y = nY; CoorMinReal.x = i; CoorMinReal.y = (int)dResultY; }*/ } //输出BC跨最大弯矩影响系数 CString strY2=_T(""); strY2.Format(_T("%d"),CoorMaxReal.y); pDC->TextOut(CoorMaxDraw.x-10,CoorMaxDraw.y-25,strY2); //输出AB跨最大弯矩影响系数 /*CString strY1=_T(""); strY1.Format(_T("%d"),abs(CoorMinReal.y)); pDC->TextOut(CoorMinDraw.x-15,CoorMinDraw.y+5,strY1);*/ pDC->SelectObject(pOldPen); newPen.DeleteObject(); }
InfluenceLineDlg.cpp
// InfluenceLineDlg.cpp : 实现文件 // #include “stdafx.h” #include “InfluenceLine.h” #include “InfluenceLineDlg.h” #include “afxdialogex.h” #include “CCalculation.h” #include “CDrawLine.h” #ifdef _DEBUG #define new DEBUG_NEW #endif // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 class CAboutDlg : public CDialogEx { public: CAboutDlg(); // 对话框数据 enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) END_MESSAGE_MAP() // CInfluenceLineDlg 对话框 CInfluenceLineDlg::CInfluenceLineDlg(CWnd* pParent /=NULL/) : CDialogEx(CInfluenceLineDlg::IDD, pParent) , m_dLength3(0) , m_dEffCoeff(0) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); CCalculation calInit; calInit.Initlize(); m_dLength1 = calInit.GetSpanL1(); m_dLength2 = calInit.GetSpanL2(); m_dLength3 = calInit.GetSpanL3(); m_dEffCoeff = calInit.GetEffectCoeffient(); } void CInfluenceLineDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_dLength1); DDX_Text(pDX, IDC_EDIT2, m_dLength2); DDX_Control(pDX, IDC_INFLUENCELINE_DRAW, m_picDraw); DDX_Text(pDX, IDC_EDIT4, m_dLength3); DDX_Text(pDX, IDC_EDIT_COEFFICIENT, m_dEffCoeff); } BEGIN_MESSAGE_MAP(CInfluenceLineDlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON_INFLUENCELINE, &CInfluenceLineDlg::OnBnClickedButtonInfluenceline) ON_BN_CLICKED(IDC_BUTTON_EFFECT_COEFFIENT, &CInfluenceLineDlg::OnBnClickedButtonEffectCoeffient) END_MESSAGE_MAP() // CInfluenceLineDlg 消息处理程序 BOOL CInfluenceLineDlg::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: 在此添加额外的初始化代码 return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } void CInfluenceLineDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialogEx::OnSysCommand(nID, lParam); } } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CInfluenceLineDlg::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(); //初始化影响线 CWnd *pWnd = GetDlgItem(IDC_INFLUENCELINE_DRAW); CDrawLine Draw; Draw.DrawInfulenceLine(pWnd,m_dLength1,m_dLength2); } } //当用户拖动最小化窗口时系统调用此函数取得光标 //显示。 HCURSOR CInfluenceLineDlg::OnQueryDragIcon() { return static_cast(m_hIcon); } //绘制影响线按钮 void CInfluenceLineDlg::OnBnClickedButtonInfluenceline() { // TODO: 在此添加控件通知处理程序代码 UpdateData(TRUE); if (m_dLength1<30 || m_dLength1>160 || m_dLength2<30 || m_dLength2>160) { AfxMessageBox(_T("连续梁适用跨度为30~160m!")); return; } //绘制影响线 CWnd *pWnd = GetDlgItem(IDC_INFLUENCELINE_DRAW); CDrawLine Draw; Draw.DrawInfulenceLine(pWnd,m_dLength1,m_dLength2); } //计算效应系数按钮 void CInfluenceLineDlg::OnBnClickedButtonEffectCoeffient() { // TODO: 在此添加控件通知处理程序代码 UpdateData(TRUE); if (m_dLength3<2 || m_dLength3>10 ) { AfxMessageBox(_T(“车辆前后轮间距应为2~10m!”)); return; } CCalculation calEfCo(m_dLength1,m_dLength2,m_dLength3); m_dEffCoeff = calEfCo.GetEffectCoeffient(); UpdateData(FALSE); }
四、项目完整代码实现
链接:
https://pan.baidu.com/s/19M8uqqfaS8c9JCDG9Tn3Vg
提取码:v52z
五、附录
影响线计算:





One thought on “两跨连续梁影响线绘制-附源码”
老大牛逼啊,关注你博客了