本站首页    管理页面    写新日志    退出


«November 2025»
1
2345678
9101112131415
16171819202122
23242526272829
30


公告

谦卑,荣誉,牺牲,英勇,怜悯,诚实,精神,公正。


我的分类(专题)

日志更新

最新评论

留言板

链接

 

 


Blog信息
blog名称:
日志总数:183
评论数量:698
留言数量:7
访问次数:3042486
建立时间:2005年12月29日




[编程学习]Visual C++6.0实现动态曲线4种方法
网上资源

newqiang 发表于 2006/3/9 11:30:31

  在实验和生产中,我们常常需要对被监测的对象进行实时监控,比如对现场的温度等环境因素进行实时数据采集,然后传输到主控制计算机,以动态曲线的方式显示出来,便于人们对现场的了解和控制。 2.用Visual C++实现动态曲线的绘制有4种方法。(1)使用消隐。(2)使用重绘。其中重绘按照原理的不同又分为3种。 2.1消隐。其实消隐的方法很简单,主要使用CDC类的成员函数SetROP2 。该函数原型为int SetROP2( int nDrawMode )。参数nDrawMode为新的绘制方式。该函数用来设置当前绘制方式,绘制方式说明画笔和被填充对象的内部如何与屏幕表面已有的颜色组合。我们选用R2_XORPEN绘制方式——画笔颜色和屏幕颜色的组合,但不同时在两者之中,最终像素=画笔XOR屏幕像素。要实现动态曲线只需在这种绘制方式下在原有曲线的位置上再绘一次,以消隐掉原有曲线,再绘制新的曲线,如此重复,就可形成动态曲线。 2.2重绘。在重绘中都要使用到这样一个函数:CDC类成员函数BitBlt 。原型为BOOL BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop )。该函数将一个位图从源设备描述表拷贝到CDC的设备描述表中。 2.2.1原理1:设置一个后台设备环境。所有的绘图工作都在后台完成,然后通过BitBlt 函数拷贝到当前设备环境。这种方法要求后台每次都全部重绘,包括坐标、字符说明、曲线等。 2.2.2应用举例: 在OnTimer 函数中每隔一定时间进行重绘。 void CDrawView::OnTimer(UINT nIDEvent) {        // TODO: Add your message handler code here and/or call default        DrawPicture();      // 画图函数 } void CDrawView::DrawPicture() {     pBackDC->PatBlt(0,0,winx, winy, PATCOPY);        //画坐标轴及刻度        DrawCoordinate(pBackDC ,BLACKPEN, MainWindowLeft,MainWindowBottom - MAINHEIGHT, MainWindowLeft + MAINWIDTH, MainWindowBottom);        //标出x坐标刻度值        WriteCoordinateX(pBackDC, BLACKPEN, MainWindowLeft,MainWindowLeft + MAINWIDTH, MainWindowBottom);        //标出y坐标刻度值        WriteCoordinateY(pBackDC,BLACKPEN,MainWindowLeft,MainWindowBottom );        //输出实际宽度值        WriteMessage(pBackDC,MainWindowLeft,MainWindowBottom,MAINHEIGHT );     if ( pBackDC != NULL )        { //画曲线图        DrawGraph(pBackDC,REDPEN,MainWindowLeft+MAINWIDTH,MainWindowBottom);              CDC *pDC = GetDC();               if (pDC != NULL)               { //调用OnDraw()函数,将曲线图显示在屏幕中                      OnDraw(pDC);                          ReleaseDC(pDC);               }        } } void CDrawView::OnDraw(CDC* pDC) {        CDrawDoc* pDoc = GetDocument();        ASSERT_VALID(pDoc);        // TODO: add draw code for native data here        if (pDC != NULL)               pDC->BitBlt(0,0,winx, winy, pBackDC, 0, 0, SRCCOPY); } 2.2.3原理2:设置一个后台设备环境(如图2),其大小与当前设备环境相同(如图1)。但主要绘图工作都在当前设备环境进行。例如设当前设备环境大小为200×100,曲线点之间的间距offset=5,左上角顶点在屏幕中的坐标为(200,100)。当所绘制的曲线横坐标X﹤400时,就在当前设备环境绘制曲线;当横坐标X﹥400时,就从前设备环境把坐标点(205,100)的右下部分用函数BitBlt拷贝到矩形区范围为(0,0,195,100)的后台设备环境中,然后清除当前设备环境,接着再用函数BitBlt从后台设备环境中把曲线拷贝到矩形区范围为(200,100,195,100)的当前设备环境中,最后再在曲线尾画上当前的数据点,如此循环。   (200,100)                         (0,0)              200×100                              200×100 图1:当前设备环境                   图2:后台设备环境 2.2.4应用举例: void CAnimateLineView::OnTimer(UINT nIDEvent) {        // TODO: Add your message handler code here and/or call default        CClientDC dc(this);        static int x=200;        static int y=200;        CPen pen1(PS_SOLID,0,RGB(255,255,255));        CPen *oldpen1=NULL;        oldpen1=dc.SelectObject(&pen1);        x=x+offsetx;        if(x<=400)        {               dc.MoveTo(x-offsetx,y);               y=200-rand()%90;               dc.LineTo(x,y);        }        else{               CRect rect(200,100,400,200);               CBrush bkbrush(HS_CROSS,RGB(0,128,0));               m_dc.BitBlt(0,0,195,100,&dc,205,100,SRCCOPY);               dc.SetBkColor(RGB(0,0,0));               dc.FillRect(rect,&bkbrush);               dc.BitBlt(200,100,195,100,&m_dc,0,0,SRCCOPY);               dc.MoveTo(395,y);               y=200-rand()%90;               dc.LineTo(400,y);}        dc.SelectObject(oldpen1);        CView::OnTimer(nIDEvent); } 2.2.5原理3:设置一个后台设备环境,其宽度为当前设备环境的两倍,高度相同。绘图工作都在后台设备环境进行。例如设当前设备环境大小为200×100(如图1),则后台设备环境为400×100(如图2),曲线点之间的间距offset=10,左上角顶点在屏幕中的坐标为(200,100)。①当在后台设备环境中所绘制的曲线横坐标0﹤X﹤200时只需将前半部分区域拷贝到当前设备环境就行了;②当横坐标200﹤X﹤400时,将宽度为200的矩形区域依次向后半部分移动10个单位取出拷贝到当前设备环境;③当X﹥400时,将后半部分拷贝到当前设备环境,并清除前半部分。④当第2次0﹤X﹤200时,将后半部分矩形区域依次向后半部分移动10个单位拷贝到当前设备环境,并将实时曲线画在前半部分然后将其拷贝到当前设备环境的末尾;⑤当200﹤X﹤400时,清除后半部分,并将前半部分矩形区域依次向后移动10个单位拷贝到当前设备环境,在后半部分绘制实时曲线然后将其拷贝到当前设备环境的末尾;⑥当再次X﹥400时,回到④,如此循环下去就能形成动态曲线。   (200,100)   200×100 图1:当前设备环境     宽度为200,不停的向右移 (0,0)                   200                      400   (200+200)×100 图2:后台设备环境 2.2.6应用举例: void CLineView::OnTimer(UINT nIDEvent) {        // TODO: Add your message handler code here and/or call default        static int x=0;        static int y=0;        static int control=0;        CClientDC dc(this);        CRect rect(0,0,200,100);        CRect rect1(200,0,400,100);        CBrush bkbrush(HS_CROSS,RGB(0,128,0));        x=x+offset;        CPen pen1(PS_SOLID,0,RGB(255,255,255));        CPen *oldpen1=NULL;        oldpen1=m_dc.SelectObject(&pen1);        if(x<=200)        {               m_dc.MoveTo(x-offset,y);               y=100-rand()%90;               m_dc.LineTo(x,y);               if(control==0)                      dc.BitBlt(200,100,200,100,&m_dc,0,0,SRCCOPY);              else               {                      dc.BitBlt(200,100,200-x,100,&m_dc,x+200,0,SRCCOPY);                      dc.BitBlt(400-x,100,x,100,&m_dc,0,0,SRCCOPY);               }        }        if(x<=400&&x>200)        {               if(control==1)               {                      dc.BitBlt(200,100,200,100,&m_dc,x-200,0,SRCCOPY);                      m_dc.FillRect(rect1,&bkbrush);                      control=0;               }               m_dc.MoveTo(x-offset,y);              y=100-rand()%90;              m_dc.LineTo(x,y);              dc.BitBlt(200,100,200,100,&m_dc,x-200,0,SRCCOPY);       }       if(x>400)       {              x=0;              dc.BitBlt(200,100,200-x,100,&m_dc,x+200,0,SRCCOPY);              m_dc.SetBkColor(RGB(0,0,0));             m_dc.FillRect(rect,&bkbrush);              control=1;       }        dc.SelectObject(oldpen1);            CView::OnTimer(nIDEvent); } 2.3总结 消隐的方法虽然简单,但不适用于实时监控。当图形区域要求参数说明和时间同时移动时,重绘中的第2和第3种方法实现起来比较麻烦。重绘中的第1种方法适用性较强,效果最好。  [原创 2006-02-21 21:25:53 | 发表者: 鸽子情缘]   


阅读全文(31541) | 回复(36) | 编辑 | 精华
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

rudy(游客)发表评论于2007/8/6 16:27:20

老大,您能不能发个源码给我,我的邮箱beyondsmt@163.com 谢谢!


个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

数据库中不存在(游客)发表评论于2007/7/30 10:17:11

我的天啊,我还有得发么?> xc2oo4@sina.com

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

Lin(游客)发表评论于2007/6/18 22:45:02

我也想要一份源码,能给我发一份吗,急 太感谢了 我的邮箱是 linglinlin3294@hotmail.com

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

zcxneu(游客)发表评论于2007/5/3 11:14:33

您好,可以给我一份源码吗?zcxneu@163.com

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

飞鹏(游客)发表评论于2007/5/2 11:26:52

楼主,我也想一份原代码,可以吗?  谢谢! ningpengfei158@163.com

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

mxz(游客)发表评论于2007/4/3 17:26:45

这个我也希望能得到一份源代码,谢谢!能否发到我邮箱。mengxuezhen@gmail.com  

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

xiaofu(游客)发表评论于2007/3/9 9:31:27

楼主,麻烦你给我发一份源码好吗,多谢了!

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

blue(游客)发表评论于2007/2/13 10:13:49

您好楼主,能不能发给我您的源码,我想学习一下 blue2342@sina.com

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

joseph_gary(游客)发表评论于2007/1/23 10:12:28

请问能否给出个通过设置关键点手动修改曲线的办法呢?我曾经写过个类,可惜我的曲线的数学模型写的不好,所以曲线有些失真,不知道能否给出个比较好的数学模型。谢谢了。邮箱:swordpeter1982@hotmail.com. 以下为blog主人的回复:  我不知道你说的数学模型是什么.也许和曲线有关吧,那应该看你需要什么样的数学模型了.

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:Visual C++6.0实现动态曲线4种方法
网上资源

wdt(游客)发表评论于2007/1/19 11:53:14

可否发份给我学习学习。谢谢。 dingdingcandy@163.com

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


» 1 2 3 4 »

发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.719 second(s), page refreshed 144803305 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号