mfc绘制曲线
2017-12-06 21:04
162 查看
自带库绘制
用mfc自带的绘图函数绘制一个sin曲线,可以说是非常费力和傻了,基于对话框程序在onPaint()函数中添加绘制代码。效果也并不是很好。void CdrawLineDlg::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 { CPaintDC dc(this); // 用于绘制的设备上下文 HPEN pen = CreatePen(PS_SOLID, 2, RGB(rand() % 256, rand() % 256, rand() % 256)); //选择画笔 HPEN oldPen = (HPEN)SelectObject(dc, pen); //指定原点 dc.SetViewportOrg(80, 180); SetTextColor(dc,RGB(255, 0, 0)); //绘制横坐标 CString sPIText[] = { "-1/2π","1/2π","π","3/2π","2π","5/2π","3π","7/2π","4π","9/2π","5π" }; for (int n = 0; n<10; n++) { LineTo(dc,60 * n, 0);//坐标横线 LineTo(dc,60 * n, -5); MoveToEx(dc,60 * n, 0,NULL); TextOut(dc,60 * n - sPIText .GetLength() * 3, 16, sPIText , sPIText .GetLength()); } MoveToEx(dc,0, 0,NULL); CString sTemp; //绘制纵坐标 for (int n = -4, nTemp = 0; nTemp <= 180; n++, nTemp = 60 * n) { LineTo(dc,0, 60 * n); LineTo(dc,5, 60 * n); MoveToEx(dc,0, 60 * n,NULL); sTemp.Format("%d", -n); TextOut(dc,10, 60 * n, sTemp,sTemp.GetLength()); } double y, radian; //绘制相关曲线 for (int x = -60; x<600; x++) { //弧度=X坐标/曲线宽度*角度*π //Y坐标=振幅*曲线宽度*sin(弧度) radian = x / ((double)60 * 2)*PI; y = sin(radian) * 2 * 60; MoveToEx(dc,(int)x, -(int)y,NULL); LineTo(dc,(int)x, -(int)y); } //恢复画笔 SelectObject(dc, oldPen); CDialogEx::OnPaint(); } }
TeeChart控件绘制
控件下载(搬运):https://pan.baidu.com/s/1o69nOZS安装参考:https://www.cnblogs.com/qiengo/p/4238567.html
动态曲线绘制参考:http://blog.csdn.net/zang141588761/article/details/50536788
这个扩展的控件可以说是非常好用的了。放到对话框当中,直接就可以对其添加变量进行画图操作了。
动态绘制主要是维护两个数组,一个是横坐标,一个是待写入数据的纵坐标。根据定时器不断左移数组完成动态绘制。我这里用到了6个图表,其中第一第二 第四第五都是3条曲线,第二2条,第六一条。定义六个数组。
double m_ThumbArray[3][32]; //大拇指角度数组 CSeries LineThumb[3]; //大拇指曲线 double m_IndexArray[3][32]; //食指角度数组 CSeries LineIndex[3]; //食指曲线 double m_MiddleArray[2][32]; //中指角度数组 CSeries LineMiddle[2]; //中指曲线 double m_RingArray[3][32]; //无名指角度数组 CSeries LineRing[3]; //无名指曲线 double m_LittleArray[3][32]; //小指角度数组 CSeries LineLittle[3]; //小指曲线 double m_BaseArray[32]; //掌腕关节角度数组 CSeries LineBase; //掌腕关节曲线 double m_X[32]; unsigned int m_count; const size_t m_Length = 32;
六个图表关联变量:
CTchart1 CThumb; CTchart1 CIndex; CTchart1 CMiddle; CTchart1 CRing; CTchart1 CLittle; CTchart1 CBase;
数组左移函数
//数组左移 void LeftMoveArray(double* ptr, size_t length, double data) { for (size_t i = 1; i<length; ++i) { ptr[i - 1] = ptr[i]; } ptr[length - 1] = data; }
画曲线函数,这里还调用了父窗口的数据写入曲线数据数组。
void CLineChart::drawMoving() { HWND hWnd = ::FindWindow(NULL, _T("数据手套数据读取面板")); //得到对话框的句柄 GloveSampleDlg * dlg = (GloveSampleDlg*)GloveSampleDlg::FromHandle(hWnd); //由句柄得到对话框的对象指针 LeftMoveArray(m_X, m_Length, m_count); for (int i = 0; i < 3; i++) { LeftMoveArray(m_ThumbArray[i],m_Length, dlg->angle[i]); //获取大拇指角度 LeftMoveArray(m_IndexArray[i], m_Length, dlg->angle[i+3]); //获取食指角度 if (i < 2) { LeftMoveArray(m_MiddleArray[i], m_Length, dlg->angle[i+6]); //获取中指角度 } LeftMoveArray(m_RingArray[i], m_Length, dlg->angle[i+8]); //获取无名指角度 LeftMoveArray(m_LittleArray[i], m_Length, dlg->angle[i + 11]); //获取小指角度 } LeftMoveArray(m_BaseArray, m_Length, dlg->angle[14]); //获取掌腕关节角度 for (int i = 0; i < m_Length; i++) { for (int j = 0; j < 3; j++) { LineThumb[j].AddXY(m_X[i], m_ThumbArray[j][i], NULL, NULL); LineIndex[j].AddXY(m_X[i], m_IndexArray[j][i], NULL, NULL); if (j < 2) { LineMiddle[j].AddXY(m_X[i], m_MiddleArray[j][i], NULL, NULL); } LineRing[j].AddXY(m_X[i], m_RingArray[j][i], NULL, NULL); LineLittle[j].AddXY(m_X[i], m_LittleArray[j][i], NULL, NULL); } LineBase.AddXY(m_X[i], m_BaseArray[i], NULL, NULL); } }
绘制按键消息响应函数
// CLineChart 消息处理程序 void CLineChart::OnBnClickedDrawline() { // 点击绘图按钮绘图 for (int i = 0; i < 3; i++) { LineThumb[i]= (CSeries)CThumb.Series(i); LineThumb[i].Clear(); ZeroMemory(&m_ThumbArray[i], sizeof(double)*m_Length); LineIndex[i] = (CSeries)CIndex.Series(i); LineIndex[i].Clear(); ZeroMemory(&m_IndexArray[i], sizeof(double)*m_Length); if (i < 2) { LineMiddle[i] = (CSeries)CMiddle.Series(i); LineMiddle[i].Clear(); ZeroMemory(&m_MiddleArray[i], sizeof(double)*m_Length); } LineRing[i] = (CSeries)CRing.Series(i); LineRing[i].Clear(); ZeroMemory(&m_RingArray[i], sizeof(double)*m_Length); LineLittle[i] = (CSeries)CLittle.Series(i); LineLittle[i].Clear(); ZeroMemory(&m_LittleArray[i], sizeof(double)*m_Length); } LineBase = (CSeries)CBase.Series(0); LineBase.Clear(); ZeroMemory(&m_BaseArray, sizeof(double)*m_Length); KillTimer(0); for (size_t i = 0; i<m_Length; ++i) { m_X[i] = i; } m_count = m_Length; SetTimer(0, 20, NULL); }
定时器,隔一段时间调用drawMoving()函数实现动态绘制
void CLineChart::OnTimer(UINT_PTR nIDEvent) { if (0 == nIDEvent) { ++m_count; drawMoving(); } CDialogEx::OnTimer(nIDEvent); }
相关文章推荐
- TeeChart在MFC中实时曲线绘制的应用
- 基于MFC串口编程和曲线图绘制(visual studio2008,Teechart绘图控件)的程序总结
- MFC中绘制动态曲线
- MFC绘制动态曲线,用双缓冲绘图技术防闪烁
- MFC GDI 曲线图绘制
- MFC 曲线图绘制
- 如何用MFC在窗口中绘制曲线
- MFC 使用双缓冲技术绘制坐标曲线
- MFC绘制动态曲线,用双缓冲绘图技术防闪烁
- MFC绘制动态曲线,用双缓冲绘图技术防闪烁
- MFC 动态绘制曲线 适用于串口数据接收显示
- MFC中绘制动态曲线
- MFC绘制动态曲线,用双缓冲绘图技术防闪烁
- MFC里多文档多视图+多线程动态计算、绘制曲线
- MFC之GDI GDI+ 一键绘制正弦曲线图
- MFC运用GraphicsPath绘制曲线、选择曲线(判断点是否在曲线上)
- [转载] MFC绘制动态曲线,用双缓冲绘图技术防闪烁
- MFC绘制动态曲线,用双缓冲绘图技术防闪烁
- MFC中绘制动态曲线
- MFC/VC++ 绘制正弦曲线