mfc绘制曲线

来源:互联网 发布:淘宝货到付款怎么买 编辑:程序博客网 时间:2024/06/07 03:58

自带库绘制

用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[n].GetLength() * 3, 16, sPIText[n], sPIText[n].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);}
原创粉丝点击