地質、氣象、交通、林業等領域需視覺化大量空間分布數據。傳統表格輸入方式不適用於龐大數據集。本文介紹一種基於 C++ 與 FoxPro 資料庫的三維視圖繪製方法,核心創新在於「多邊形消隱法」:以背景色多邊形覆蓋被遮擋線段,實現簡單高效的隱藏面移除。
.dbf 欄位 DT1 存放繪圖數據DH 填入逗號 ","COPY TO data.h FIELDS DT1,DH DELIMITED WITH BLANKdata.h:首加 A={、尾加 };#include "data.h" 直接存取陣列 A[] / mv[]觀察者視角下,較近排 (Y 較大) 的表面會遮擋較遠排。以當前排點 + 前一排對應點構成多邊形,填充背景色,即可「擦除」被遮擋的線段。無需複雜幾何運算,純 2D 繪圖 API 即可實現。
// 第 j 排、第 i 點的屏幕座標
PointTable[i].x = i * SCALE2 + j * SCALE4; // X 向縮放 + Y 排偏移
PointTable[i].y = yy[j] - (PointTable[i].x - PointTable[0].x) * ANGLE
- (mv[j * MAXPTS + i] * SCALE3); // Y 基線 - 視角傾斜 - Z 高度
MOVE:繪圖起始 Y 座標SCALE1:Y 排間距SCALE2:X 向縮放SCALE3:Z 數值縮放SCALE4:Y 排 X 偏移 (視差)ANGLE:視角傾斜係數
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
SetMapMode(hDC, MM_TEXT);
// 筆刷準備
HPEN hGreenPen = CreatePenIndirect(&lpGreen); // 網線
HPEN hWhitePen = CreatePenIndirect(&lpWhite); // 最後一排消隱
HPEN hBlackPen = CreatePenIndirect(&lpBlack); // 中間排消隱
HBRUSH hWhiteBrush = GetStockObject(WHITE_BRUSH);
HBRUSH hBlackBrush = GetStockObject(BLACK_BRUSH);
for (j = 0; j < MAXPTS; ++j) {
yy[j] = MOVE + j * SCALE1;
// 計算當前排所有點座標
for (i = 0; i < MAXPTS; ++i) {
PointTable[i].x = i*SCALE2 + j*SCALE4;
PointTable[i].y = yy[j] - (PointTable[i].x - PointTable[0].x)*ANGLE
- (mv[j*MAXPTS+i] * SCALE3);
}
// 繪 Y 向網線 (連接前一排)
if (j > 0) {
SelectObject(hDC, hGreenPen);
for (i = 0; i < MAXPTS; ++i) {
MoveTo(hDC, mx[i], my[i]);
LineTo(hDC, PointTable[i].x, PointTable[i].y);
}
}
// 封閉多邊形頂點 (加底部兩點)
PointTable[MAXPTS].x = PointTable[MAXPTS-1].x;
PointTable[MAXPTS].y = PointTable[MAXPTS-1].y + 20;
PointTable[MAXPTS+1].x = PointTable[0].x;
PointTable[MAXPTS+1].y = PointTable[0].y + 20;
// 消隱:填充多邊形
if (j == MAXPTS-1) { // 最後一排用白色 (背景)
SelectObject(hDC, hWhitePen);
SelectObject(hDC, hWhiteBrush);
} else { // 中間排用黑色 (遮蓋前排)
SelectObject(hDC, hBlackPen);
SelectObject(hDC, hBlackBrush);
}
Polygon(hDC, PointTable, MAXPTS+2); // 關鍵消隱呼叫
// 繪 X 向網線 (當前排)
for (i = 0; i < MAXPTS-1; ++i) {
SelectObject(hDC, hGreenPen);
MoveTo(hDC, PointTable[i].x, PointTable[i].y);
LineTo(hDC, PointTable[i+1].x, PointTable[i+1].y);
}
// 保存當前排座標供下一排 Y 向連線
for (i = 0; i < MAXPTS; ++i) {
mx[i] = PointTable[i].x;
my[i] = PointTable[i].y;
}
}
EndPaint(hWnd, &ps);
break;
| 優勢 | 說明 |
|---|---|
| 數據量大 | 陣列儲存於 .h,編譯期嵌入,無運行期解析開銷 |
| 參數靈活 | 視角、縮放、起始點全在 data.h 修改即可 |
| 消隱簡單 | 多邊形填充法無需 Z-buffer、光線追蹤等複雜演算法 |
| 程式碼精簡 | 核心繪圖邏輯 < 100 行 |
適用:大規模規則網格空間數據 (地形高程、溫度場、濃度分布等) 三維可視化。