傳統物理儀表盤因成本高昂、易損壞且維修困難等缺陷,在現代控制系統中逐漸被計算機虛擬儀表盤所取代。特別是在仿真領域,虛擬儀表盤已成為主流解決方案。然而,儀表盤軟體開發面臨諸多技術挑戰,如圖像縮放、漫遊、指針旋轉等。本文介紹如何利用 C++ Builder 結合 Windows GDI(圖形設備介面)技術,有效解決虛擬儀表盤開發中的核心難題。
儀表盤指針的繪製是虛擬儀表盤開發中最常遇到的問題。簡單應用常用線段模擬指針,但真實儀表盤往往需要不規則圖形指針,這就涉及到位圖旋轉技術。Windows GDI 提供了獨立於硬體的繪圖抽象層,通過 XFORM 資料結構實現座標轉換:
typedef struct _XFORM {
FLOAT eM11; // 水平縮放因子 / 旋轉角度餘弦
FLOAT eM12; // 水平比例因子 / 旋轉角度正弦
FLOAT eM21; // 垂直比例因子 / 旋轉角度負正弦
FLOAT eM22; // 垂直縮放因子 / 旋轉角度餘弦
FLOAT eDx; // 水平轉換偏移
FLOAT eDy; // 垂直轉換偏移
} XFORM;
座標轉換公式為:
X' = x * eM11 + y * eM21 + eDx
Y' = x * eM12 + y * eM22 + eDy
以下完整程式碼演示如何根據指針數值、量程範圍、角度範圍將標準水平指針位圖繞中心點旋轉繪製:
void __fastcall TForm1::rotatedraw(int x, int y,
float ff, float hr, float lr,
float scale0, float scale1, float rscale,
Graphics::TBitmap *p) {
XFORM xform;
float tf, f;
// 防止除零導致浮點溢出
if (x == 0) x = 0.0001;
// 旋轉角度換算:將數值映射到角度
tf = (ff - lr) * (scale0 - scale1) / (hr - lr) - rscale;
f = 3.14159265 * tf / 180; // 角度轉弧度
// 設定旋轉變換矩陣
xform.eM11 = cos(f);
xform.eM12 = sin(f);
xform.eM21 = -sin(f);
xform.eM22 = cos(f);
// 計算平移偏移量,確保指針繞中心點 (x,y) 旋轉
xform.eDx = x - (sqrt(x*x + y*y)) * cos(f + atan(y/x));
xform.eDy = y - (sqrt(x*x + y*y)) * sin(f + atan(y/x));
// 設置世界座標變換模式
SetGraphicsMode(Form1->Canvas->Handle, GM_ADVANCED);
SetWorldTransform(Form1->Canvas->Handle, &xform);
// 透明繪製:將位圖背景色設為透明
p->Transparent = true;
p->TransparentColor = p->Canvas->Pixels[0][0];
// 繪製指針
Form1->Canvas->Draw(x, y, p);
// 恢復預設座標系統
p->Transparent = false;
xform.eM11 = 1; xform.eM12 = 0;
xform.eM21 = 0; xform.eM22 = 1;
xform.eDx = 0; xform.eDy = 0;
SetWorldTransform(Form1->Canvas->Handle, &xform);
}
透過設置專用定時器 PointTimer,間隔 30 毫秒(刷新率 > 24Hz),利用人眼視覺暫留效應實現指針平滑移動。只需根據數值變化計算適當增減幅度,即可達到連續動畫效果。
當儀表盤圖像大於螢幕顯示區域時,需實現畫面拖曳漫遊。解決方案:在應用程式視窗中啟用水平/垂直捲軸(HorzScrollBar、VertScrollBar),動態繪製座標加上捲軸偏移量:
// 繪製時使用的實際座標
X - HorzScrollBar->Position
Y - VertScrollBar->Position
// 漫遊操作時更新捲軸位置
HorzScrollBar->Position = HorzScrollBar->Position + movx;
VertScrollBar->Position = VertScrollBar->Position + movy;
Stretch = TRUE,自動適應視窗大小變化避免大量圖元重繪,採用背景圖複製 + 顏色修改策略。動態時利用透明技術,調用 CopyRect 在指定矩形區域實現字符亮滅變化,同樣適用於特殊圖形動態顯示。
C++ Builder 結合 Windows SDK 與 GDI 技術,有效解決了虛擬儀表盤的指針旋轉、畫面漫遊、縮放及發光字符等核心問題。GDI 獨立於硬體的特性確保了跨平台穩定性,相關方法已在多個專案中驗證,滿足工業級虛擬儀表盤的圖形變化需求。