VC++畫動態曲線
在實驗和生產中,我們常常需要對被監測的物件進行實時監控,比如對現場的溫度等環境因素進行實時資料採集,然後傳輸到主控制計算機,以動態曲線的方式顯示出來,便於人們對現場的瞭解和控制。
(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)的當前裝置環境中,最後再在曲線尾畫上當前的資料點,如此迴圈。
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時,回到④,如此迴圈下去就能形成動態曲線。
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種方法適用性較強,效果最好。
相關文章
- VC++ Bresenham畫線例項C++
- canvas小畫板--(1)平滑曲線Canvas
- 漫畫:程式語言學習曲線
- c# winform之繪畫及畫直曲線相關C#ORM
- canvas進階——如何畫出平滑的曲線?Canvas
- iOS開發之畫圖板(貝塞爾曲線)iOS
- pyqt5+matplotlib繪製動態雙y軸曲線QT
- Flutter 自定義元件之貝塞爾曲線畫波浪球Flutter元件
- 漫畫:7種程式語言的學習曲線
- 從一組漫畫看程式語言學習曲線
- 機器學習中的PR曲線和ROC曲線機器學習
- Windows下的VC++動態連結庫程式設計WindowsC++程式設計
- 動漫街道場景高畫質動態桌布
- three.js 曲線JS
- 【CSS】曲線陰影CSS
- 庫克曲線(轉載)
- 圓錐曲線14
- 圓錐曲線15
- 漫畫:什麼是動態規劃?動態規劃
- Flutter 實戰 - 用貝塞爾曲線畫一個帶文字的波浪球 WidgetFlutter
- [動態代理三部曲:上] – 動態代理是如何”坑掉了”我4500塊錢
- [動態代理三部曲:上] - 動態代理是如何"坑掉了"我4500塊錢
- [動態代理三部曲:下] - 從動態代理,看Retrofit的原始碼實現原始碼
- 用canvas繪製一個曲線動畫——深入理解貝塞爾曲線Canvas動畫
- 動態規劃-----線性動態規劃
- polarbear北極熊高畫質動態桌布
- Mac灕江景色高畫質動態桌布Mac
- [動態代理三部曲:中] - 從動態代理,看Class檔案結構定義
- 機器學習之學習曲線機器學習
- Error Curves——錯誤曲線Error
- Android 貝塞爾曲線Android
- Python擬合曲線Python
- Flutter 實現平滑曲線折線圖Flutter
- VC++環境下選單和工具欄的動態修改技術 (轉)C++
- 5k高畫質粉色動態桌布分享
- 2022虎年高畫質動態桌布
- Living Wallpaper HD for Mac高畫質動態桌布Mac
- 動態開點線段樹