BGI 是 Borland Graphic Interface 繪圖函式庫的縮寫, 在標準的 C 語言中, 是沒有繪圖函數的, 早年 (~1985) Borland 公司為 Turbo C/C++ 系統寫的繪圖函式庫, 那個年代 PC 是只有文字介面的 (24列80行), 640x480 的解析度就叫做高解析度圖形介面了XD。視窗系統在 1990 年代出現以後, 當然 BGI 也早就進入歷史了... Borland C/C++ 是 Turbo C/C++ 的後續版本, 不過在 1997 年也走入歷史, 最後的版本是 Borland C/C++ 5.02。Borland 公司在 1997 開發一套快速化程式開發 (RAD, Rapid Application Development) 的整合開發環境 (IDE, Integrated Development Environment) C++ Builder (BCB) 接續 Borland C++, 在 2008 年這個產品以及整個軟體部門 CodeGear 賣給了 Embarcadero Technologies。
簡史: Turbo C++ → Borland C++ → Borland C++Builder → CodeGear C++Builder → Embarcadero C++Builder
聽起來就是很有歷史的感覺, 我們還用這個嗎? 老實說, 不太用了, 不過要上手實在簡單, 和文字介面的程式運作模型是一致的, 大家應該可以很快開始, 門檻很低, 畫出來的效果其實也還不錯... 還有環境也很簡單, 不論你是用 gcc/g++ 或是 visual C/C++, 都只要下載一個 graphics.h 檔案, 一個 libbgi.lib 檔案就 OK 了, 準備好開始了, 不小心我們就介紹完了
BGI 是過去的東西了, 可是這麼容易使用的東西, 還是很好的練習工具, 我在 Dept. CS of Univ. Colorado 網站上找到這個 WinBGIm, 用 Win32 API 重新實作了所有的函式, 是給 Dev-C/C++ 4.9.9.2 的, 不過我在 Dev-C/C++ 5.7.1, 5.11, MinGW 4.8.1, VC6, VC2008, VC2010 中編譯都只要修改非常少數的東西
VC6 | libbgi.lib |
VC08 | libbgi.lib |
VC10 | libbgi.lib, libbgi_d.lib |
DevC++4.9.9.2 | libbgi.a |
MinGW g++4.8.1(32bit) | libbgi.a |
MinGW g++4.8.1(64bit) | libbgi.a |
DevC++5.7.1(64bit) | libbgi.a |
DevC++5.11(64bit) | libbgi.a |
VC/C++ 6 | 命令列 |
VC/C++ 2008 | 命令列 cl -EHsc testBGIm.cpp libbgi.lib gdi32.lib comdlg32.lib uuid.lib oleaut32.lib ole32.lib user32.lib |
VC/C++ 2010 | IDE整合環境 檔案/新增/專案, 空專案, testBGIm 拷貝 testBGIm.cpp 到 testBGIm 資料匣 方案總管/右鍵點 testBGIm/加入現有項目, 選擇 testBGIm.cpp 專案/屬性/組態屬性/連結器/命令列/其他選項: /NODEFAULTLIB:LIBCMT
建置/組態管理員/使用中的方案組態: Debug (預設是 Debug 版本) |
DevC++ 4.9.9.2 | 工具/編譯器選項/在連結器命令列中加入以下的命令 |
MinGW g++ 4.8.1(32bit) | g++ testBGIm.cpp -o testBGIm.exe -lbgi -L. -lgdi32 -lcomdlg32 -luuid -loleaut32 -lole32 |
MinGW g++ 4.8.1(64bit) | g++ testBGIm.cpp -o testBGIm.exe -lbgi -L. -lgdi32 -lcomdlg32 -luuid -loleaut32 -lole32 -Wno-write-strings |
DevC++ 5.7.1(64bit) | 工具/編譯器選項/在連結器命令列中加入以下的命令 |
DevC++ 5.11(64bit) | 工具/編譯器選項/在連結器命令列中加入以下的命令 -L. -lbgi -lgdi32 -lcomdlg32 -luuid -loleaut32 -lole32 |
initwindow(640, 480, "First Sample"); // graphics.h 進入繪圖模式, 開啟 640 x 480 大小的繪圖視窗
...
繪圖動作
...
closegraph(); // graphics.h 中結束繪圖模式, 這一列請放在 system("pause") 之後
程式在執行的時候可以藉由 graphics.h 中定義的函式 getmaxx() 及 getmaxy() 來得到螢幕的寬度及高度,例如:
int maxX, maxY;
maxX = getmaxx(); // graphics.h
maxY = getmaxy();
螢幕上可以在 x 軸(正向朝右) 0 到 maxX 以及 y 軸(正向朝下) 0 到 maxY 的範圍中作畫。
請運用 graphics.h 函式庫中
三個函式在螢幕上畫線, line() 這個函式可以指定起始點座標 (x1, y1) 及終點座標 (x2, y2), 在這之間畫一條直線。 moveto() 及 lineto() 這一組函式配合目前的游標位置 CP 也可以用來畫直線, 例如:
moveto(200, 20); // CP 移到 (200,20)
lineto(200, 80); // 畫直線到 (200,80)
lineto(300, 80); // 畫直線到 (300,80)
與
line(200, 20, 200, 80);
line(200, 80, 300, 80);
的效果完全一樣, moveto(200, 20) 將游標位置 CP 移動到 (200, 20) 的地方, lineto(200, 80) 則由 CP 的位置畫直線到 (200, 80), 並設定 CP 為 (200, 80)。
使用 lineto() 函式畫連續線段比起 line() 函式最大的好處就是程式中不需要記錄上一點的座標, 而由繪圖系統中的 CP 來記住。
注意:
如果你希望設定線段的顏色, 請以 void setcolor(int color); 函式來改變, 其中 color 的數值可以是 graphics.h 中定義的 BLACK(0), BLUE(1), GREEN(2), CYAN(3), RED(4), MAGENTA(5), BROWN(6), LIGHTGRAY(7), DARKGRAY(8), LIGHTBLUE(9), LIGHTGREEN(10), LIGHTCYAN(11), LIGHTRED(12), LIGHTMAGENTA(13), YELLOW(14), WHITE(15) 等等常數之一, 例如:
setcolor(LIGHTGREEN);
line(320, 0, 320, 479);
outtextxy(100, 200, "hello");
setcolor(LIGHTRED);
outtextxy(120, 200, "world");
就會 畫出一條亮綠色的直線, 亮綠色的文字 hello 以及亮紅色的文字 world
一個 sine 函式圖形是一個二維平面上的圖形, x 軸範圍在 -π 到 π 之間, y 軸範圍在 -1 到 1 之間, 因為這是一個連續函數, 所以不論 x 軸或是 y 軸, 我們都知道其上應該有無窮多個點。
但是在電腦螢幕上要顯示這樣子的圖形, 不可能也不需要使用無窮多個點,
不可能的原因是螢幕的解析度有限, 在文字 模式視窗只能顯示 80 個字元寬、24 個字元高, 每一個方格裡你只能顯示一個字元或是不顯示, 沒有太多的選擇。 在簡單的 BGIm 圖形模式視窗中允許你在指定的 寬度及高度 的視窗中作圖, 每一個點除了允許你畫點或是不畫點之外, 也容許你用 16 個顏色來畫點。
不需要使用無窮多點的原因是: 你的眼睛不夠好, 根本無法在螢幕上分辨距離太近的點
下圖在 BGIm 繪圖模式視窗中繪製的 sine 函數:
由於解析度比文字模式提高很多, 在上面視窗中繪製的曲線, 你已經慢慢感覺不出來它是折線了。
座標軸繪製如下:
line(0, 240, 640, 240);
line(320, 0, 320, 480);
以線段來畫出 sine 函式, 程式如下:
ix = (int) ((x = -PI) / PI * 319 + 320 + 0.5); iy = (int) (-sin(x) * 239 + 240 + 0.5); moveto(ix, iy); for (i=-318; i<=319; i++) { x = PI / 319 * i; y = sin(x); ix = i + 320; iy = (int) (-y * 239 + 240 + 0.5); lineto(ix, iy); }
座標轉換公式:
繪製 sine 函數圖形在寬 640, 高 480 的視窗中, 需要設計座標點的轉換公式如下:
實數平面 寬:2π 高:2 |
繪圖模式視窗 寬:640 高:480 |
---|---|
(x,y) | (x2,y2) |
(0, 0) | (320, 240) |
(π, 0) | (639, 240) |
(-π, 0) | (1, 240) |
(0, 1) | (320, 1) |
(0, -1) | (320, 479) |
一般化的公式應該是
實數平面 寬:2π 高:2 |
繪圖模式視窗 寬:640 高:480 |
---|---|
x y |
x2 = x / π * 319 + 320 y2 = -y * 239 + 240 |
請注意:
double x = 2.6, y = 2.4; int ix, iy; ix = (int) (x + 0.5); iy = (int) (y + 0.5);則整數變數 i 內的數值為 3, j 內的數值為 2。
setfillstyle(SOLID_FILL, RED); // 紅色
bar(100, 150, 300, 250); // left, top, right, bottom
如果想要加畫邊框,
setcolor(WHITE); // 白色
rectangle(100, 150, 300, 250); // left, top, right, bottom
回
C++ 物件導向程式設計課程
首頁
製作日期: 05/01/2016 by 丁培毅 (Pei-yih Ting) E-mail: [email protected] TEL: 02 24622192x6615 海洋大學 電機資訊學院 資訊工程學系 Lagoon |