計算機圖形學(xué)實驗指導(dǎo)書_第1頁
計算機圖形學(xué)實驗指導(dǎo)書_第2頁
計算機圖形學(xué)實驗指導(dǎo)書_第3頁
計算機圖形學(xué)實驗指導(dǎo)書_第4頁
計算機圖形學(xué)實驗指導(dǎo)書_第5頁
已閱讀5頁,還剩23頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第一章計算機圖形學(xué)的軟件開發(fā)環(huán)境

計算機圖形學(xué)中的程序都是用C語言編寫的,TurboC和VisualC++常見的兩種C涪言開發(fā)環(huán)境,

TurboC是在Dos環(huán)境下開發(fā),而VisualC++是在晅ndows環(huán)境下開發(fā)。

1.1v在TurboC環(huán)境下開發(fā)應(yīng)用程序

一些高級語言都擴充了圖形功能,這使得用戶可以不需配備專門的圖形軟件,就能在計算機上進

行圖形工作。TurboC2.0包含有460多個庫函數(shù),其中有70多個圖形函數(shù),這些函數(shù)包括了繪圖、

處理圖象及圖素、屏幕及視圖區(qū)控制、顏色及線型設(shè)置、狀態(tài)查詢和出錯處理等,這使得TurboC具

有很強的圖形功能。

1.圖形顯示器的工作方式

IBMPC機的顯示器可以在兩種基本視頻方式下工作:一種是文本方式;另一種是圖形方式。

(1)文本方式

在文本方式下,屏幕上可以顯示的最小單位是字符,字符在屏幕上以行、列排列,即我們通常見

到的情況。文本方式不同,屏幕上所顯示字符的行數(shù)和列數(shù)也不一樣,顏色也會有所區(qū)別。TurboC支

持6種不同的文本顯示方式。

(2)圖形方式

在圖形方式下,屏幕上可以控制的最小單元稱作像素(pixel),它是組成圖形的基本元素,

一般叫作“點”。通常把屏幕上所包含像素的個數(shù)叫做分辨率。分辨率越高,顯示的圖形越細致、質(zhì)

量越好,這是顯而易見的。在圖形方式卜,屏幕上每個像素的、顯示位置用點坐標系來描述。在該坐標

系中,屏幕左上角為坐標系的原點,坐標值為(0,0);水平方向為X軸,自左向右;垂直方向

為Y軸,自上向下。見下圖。

(0f0)XmaxX

Y

fmaxY

點坐標系中坐標值的范圍決定于所用顯示器的分辨率。分辨率不同,水平方向上和垂直方向上的

點數(shù)也不同,即其maxx、maxy的數(shù)值不同。就我們常用的VGA顯示器來說,它通常所用的分辨

率為6405480,即它的maxx值為639,maxy的值為479。

2.圖形函數(shù)及其用法

TurboC的圖形函數(shù)均在一個頭文件“graphics』”中定義。所以,凡是在程序中要調(diào)用這些

圖形函數(shù),都必須在源程序的開頭寫上文件包含命令:

#include<graphics.h>

(1)圖形系統(tǒng)管理

在一般默認情況下,顯示器處于文本方式下。在文本方式下,所有的圖形函數(shù)均不能應(yīng)用。因此

在調(diào)用圖形函數(shù)繪圖之前,必須先將顯示器設(shè)置為圖形模式,這就是通常所說的圖形方式初始化。在

圖形工作完畢之后,又要使顯示器回到文本方式,以便進行程序文件等的編輯工作。

?圖形方式初始化

圖形方式初始化通過函數(shù)initgraph來實現(xiàn),它的功能是通過從磁盤上裝入一個圖形驅(qū)動程序

來初始化圖形系統(tǒng),并將系統(tǒng)設(shè)置為圖形模式。其調(diào)用格式為:initgraph(int*gdriver,int

*gmodc,char*path);

調(diào)用該函數(shù)需用的三個參數(shù)含義為:

gdrivcr:是一個整型值,用來指定裝入的驅(qū)動程序名。

gmode:是一個整型值,用來設(shè)置圖形顯示模式。path:是一個字符串,用來指明強動程序所在的

路徑。

舉例:假設(shè)使用VGA顯示器,圖形顯示模式為VGAHI,即高分辨率圖形模式,分辨率為640548()。

則初始化調(diào)用方式如下:

intgdriver=VGA,gmode=VGAHI;

initgraph(&gdriver.&gmode,"c:\\tc");

?關(guān)閉圖形模式

在運行圖形程序結(jié)束后,應(yīng)及時關(guān)閉圖形模式,回到文本方式,以進行其他工作。關(guān)閉圖形模式

用函數(shù)closegraph,其調(diào)用方法為:

closegraph();(該函數(shù)不需參數(shù))

(2)繪圖函數(shù)

從理論上來說,用像素點兒乎可以畫出任何圖形,但畢竟是效率太低。為此,TurboC的BGI提

供了一些基本的繪圖函數(shù),以方便圖形設(shè)計。所有繪圖附數(shù)調(diào)用時的參數(shù),其類型均為整型,因此填

入?yún)?shù)表的參數(shù),應(yīng)為整數(shù)或整型變量

putpixel函數(shù):將指定的顏色寫到由坐標x,y所確定的點。如pulpixel(x,y,GREEN);

Iine函數(shù):在指定兩點之間畫直線。如:line(xl,yl,x2,y2);

Iineto函數(shù):從當前點畫線到指定點。如:lineto:x,y);

moveto函數(shù):把當前點移到指定點(不畫線)。如:noveto(x,y)

circle密數(shù):指定圓心和半徑畫圓。如:circle(xc,yc,r);

arc函數(shù):畫一段圓弧。要求指定圓弧所在圓的圓心、半徑,以及圓弧的起始角和終止角。

如:arc(xc,yc,angs,ange,r);

rectangle函數(shù):指定矩形的兩對角點畫一個矩形。如:rectangle(xl,yl,x2,y2);

drawpoly函數(shù):畫一條任意多邊折線。如:drawpoly(nps,xy);其中,nps為多邊折線的頂

點數(shù);xy為存放頂點坐標值的數(shù)組名。如果首尾兩點重合,則可以繪制一個任意多邊形。

(3)圖形屬性控制

圖形的屬性指顏色和線型,顏色乂有背景色和前景色之分。背景色指的是屏幕的顏色,即底色;

前景色指的是繪圖用的顏色。任何繪圖函數(shù)都是在當前顏色(背景色和前景色)和線型的狀態(tài)下作圖

的。系統(tǒng)的默認值為:背景色為黑色;前景色為白色;線型為實線。

?setbkcolor函數(shù):設(shè)置背景顏色。如:setbkcolorICOLORNAME);

setcolor函數(shù):設(shè)置前景顏色。(用法同上)

setIinestyIe函數(shù):設(shè)置線型。如:set!inestyle(LSTY,0,WIDTH);

(4)繪圖程序簡例

#include<graphics.h>

main()

/"DETECT的含義是自動檢則當前顯示器的類型,且選用最大可能的分辨率模式*/

intgd=DETECT,gm;initgraph(&gd,&gm,"f:\\tc“);

setbkcolor(LIGHTBLUE);

setcolor(RED);

circle(320,240,100);

/*getch()的含義是讀入一個字符,但不回顯在窗口中,加入這句語句的目的是防止顯示的圖像很快消失*/

getch();

closegraph();

}

1.2、在VisualC++環(huán)境下開發(fā)應(yīng)用程序

一,Windows編程基礎(chǔ)

VisualC++是可視化開發(fā)系統(tǒng),一般而言,可視化開發(fā)系統(tǒng)集成了一系列系統(tǒng)可用資源和開發(fā)工

具:程序調(diào)試工具包括源程序語法檢查、可執(zhí)行程序修改和運行監(jiān)視等;可選擇并構(gòu)成具體語句或源

程序結(jié)構(gòu)的例程庫及Help;資源管理器包括圖形化窗口及組成元素的多種對象的編輯器;應(yīng)用程序

Help和Setup開發(fā)工具包,源程序編輯器和編譯器;系統(tǒng)函數(shù)庫和系統(tǒng)函數(shù)開發(fā)工具,

在Windows的程序設(shè)計語言中,VC、VB、VJ都是“面向?qū)ο蟆钡某绦蛟O(shè)計語言。對象是Windows

的規(guī)范部件:窗II、菜單、按鈕、對話框、程序模塊都是對象。編寫Windows程序相當一部分工作是

在創(chuàng)建對象和為對象屬性賦值。對象具有規(guī)范形態(tài)和操作模式的特征。

在用vc進行編程時有兩種方法:傳統(tǒng)的編程方法方法和交互式編程方法。傳統(tǒng)的編程方法是采用

直接調(diào)用API的方法進行編程,API是Win系統(tǒng)與Win應(yīng)用程序間的標準程序接口,API為應(yīng)用程序

提供Windows系統(tǒng)特殊函數(shù)及數(shù)據(jù)結(jié)構(gòu),并且Win應(yīng)用程序可以利用標準大量API函數(shù)調(diào)用系統(tǒng)功能。

API函數(shù)的功能包括:窗口管理函數(shù)實現(xiàn)窗口的創(chuàng)建、移動和修改功能;系統(tǒng)服務(wù)函數(shù):實現(xiàn)與操作

系統(tǒng)有關(guān)的多種功能;圖形設(shè)備(GDI)函數(shù):實現(xiàn)與設(shè)備無關(guān)的圖形操作功能。交互式編程方法是采

用MFC的方法進行編程。采用交互式方法時,可視化開發(fā)平臺給出了許多選用的對象,程序員可選擇

所需對象并確定其屬性,由此搭建起應(yīng)用程序的“大框架”,并可根據(jù)需要進一步編寫必要的細節(jié)代

碼段,最后構(gòu)成完整的應(yīng)用程序。

利用WindowsAPI函數(shù)編寫Windows應(yīng)用程序必須首先了解以下內(nèi)容:

(1)窗口的概念

(2)事件驅(qū)動的概念

(3)句柄

(4)消息

⑴窗口

一個應(yīng)用程序的窗口一般包含下列成分:

最大化按鈕

控制菜單框文坤a)?他印a圖電)MA,O)格式@工及s

幻燈片斷,Q)9口”助qp

下拉菜單最小化按鈕

HfilD

標題欄

??元.9MMM星Q2

由/公a、

?個I?,個?吊3d

工作區(qū)ttaxaoim.系統(tǒng)ui

?打?”?liM

垂直滾動條

水平滾動條

制處理消息,控制通知消息,滾動條通知消息,非用戶區(qū)消息,MDI消息,DDE消息,應(yīng)用程序自定

義的消息。

二、Windows應(yīng)用程序常用消息

1.WM_LBUTTONDOWN:產(chǎn)生單擊鼠標左鍵的消息。IParam:低字節(jié)包含當前光標的X坐標值高字節(jié)包

含當前光標的Y坐標值;wParam包含一整數(shù)值以標識鼠標鍵的按下狀態(tài);MKLBUTTON按下鼠標左

鍵,MKJIBUTTON按下鼠標中鍵,MK_RBUTTON按下鼠標右鍵.此外,相似的消息還有:

WM_LBUTTONUP:放開鼠標左鍵時產(chǎn)生:

WM_RBUTTONDOWN:單擊鼠標右鍵時產(chǎn)生;

WM_RBUTTONUP:放開鼠標右鍵時產(chǎn)生:

WMLBUTTONDBLCLK:雙擊鼠標左鍵時產(chǎn)生;

WM_RBUTTONDBLCLK:雙擊鼠標右鍵時產(chǎn)生

2.WM_KEYDOWN:按下?個非系統(tǒng)鍵時產(chǎn)生的消息。系統(tǒng)鍵是指實現(xiàn)系統(tǒng)操作的組合鍵,例如Alt與

某個功能鍵的組合以實現(xiàn)系統(tǒng)菜單操作等。wParam:按下鍵的虛擬鍵碼,用以標識按下或釋放的鍵(如

F1的虛擬鍵碼在Windows」文件中定義為VKFl):IParam:記錄了按鍵的重復(fù)次數(shù)、掃描碼、轉(zhuǎn)移

代碼、先前鍵的狀態(tài)等信息。

相似的消息還有WM_KEYUP,在放開非系統(tǒng)鍵時產(chǎn)生

3.WM_CHAR:按卜一個非系統(tǒng)鍵時產(chǎn)生的消息。WParam:為按鍵的ASCII碼;IParam:與WM_KEYDOWN

的相同。

4.WM_CREATE:由CreateWindow函數(shù)發(fā)出的消息。wParam:未用;IParam:包含?個指向CREATESTRUCT

數(shù)據(jù)結(jié)構(gòu)的指針。

5.WM_CL0SE:關(guān)閉窗口時產(chǎn)生的消息。wParam和IParam均未用。

6.WM_DESTROY:由DcstroyWiodow函數(shù)發(fā)出的消息。wParam和IParam均未用。

7.WM_QUIT:由PostQuilMessage函數(shù)發(fā)出的消息,退出應(yīng)用程序時發(fā)出的消息。wParam:含退出代

碼,標識程序退出運行時的有關(guān)信息;IParam:未用

8.WM.PAINT:以下情況時將產(chǎn)生WM_PAINT消息。用戶區(qū)移動或顯示,用戶窗口改變大小,程序通過

滾動條滾動窗口,下拉式菜單關(guān)閉并需要恢復(fù)被覆蓋的部分,Windows清除對話框等對象,并需要恢

復(fù)被覆蓋的部分均產(chǎn)生WV_PAINT消息。

HWindows中的事件驅(qū)動程序設(shè)計

過程驅(qū)動程序設(shè)計和事件驅(qū)動程序設(shè)計的區(qū)別如下圖:

沸驅(qū)動雄計算平均竭

四、Windows應(yīng)用程序組成及編程步驟

1.應(yīng)用程序的組成

?個完整的Windows應(yīng)用程序通常由五種類型的文件組成。

LC語言源程序文件

2.頭文件

3.模塊定義文件

4.資源描述文件

5.項目文件

2.源程序組成結(jié)構(gòu)

WinMain和WndProc是Windows應(yīng)用程序的主體,Windows應(yīng)用程序由這兩個函數(shù)構(gòu)成基本框架。

入口函數(shù)WinMain:1.是所有應(yīng)用程序的入口,類似Main函數(shù),2.完成一系列的定義和初始化,井

產(chǎn)生消息循環(huán)。窗口函數(shù)WndProc包含各種數(shù)據(jù)類型、數(shù)據(jù)結(jié)構(gòu)與函數(shù)等。

(1)WinMain函數(shù)

WinMain函數(shù)的功能是注冊窗口類,建立窗口及執(zhí)行必要的初始化。并進入消息循環(huán),據(jù)接受的消

息調(diào)用相應(yīng)的處理過程,當消息循環(huán)檢索到WM_QUIT時終止程序運行。WinMain函數(shù)由三個基本的組

成部分:函數(shù)說明、初始化和消息循環(huán)。

WinMain函數(shù)的說明如下:

intWINAPIWinMain

(HINSTANCEhThisInst,〃應(yīng)用程序當前實例句柄

HINSTANCehPrevInst,〃應(yīng)用程序其他實例句柄

LPSTRIpszCmdLine,〃指向程序命令行參數(shù)的指針

IntnCmdShow〃應(yīng)用程序開始執(zhí)行時窗口顯示方式的整數(shù)值標識

)

注意!Win是多任務(wù)管理的,同一應(yīng)用程序的多個窗口可能會同時存,*in系統(tǒng)對每個窗II的執(zhí)行稱為

一個實例,并用一個實例句柄來唯一標識

⑵初始化

初始化包括四個步驟。窗口類的定義:定義窗口的形式與功能;窗口類的注冊:窗口類必須先注冊

后使用;創(chuàng)建窗口實例;顯示窗口。

(a)窗口類定義

通過給窗口類數(shù)據(jù)結(jié)構(gòu)WNDCLASS賦值完成,該數(shù)據(jù)結(jié)構(gòu)中包含窗口類的各種屬性。窗口類定義常用

以下函數(shù):

Loadicon:作用是在應(yīng)用程序中加載一個窗口圖標。其原型為:

HICONLoadicon(HINSTANCEhlnstance,//hlnstance圖標資源所在的模塊句柄,NULL則使用系統(tǒng)預(yù)

〃定義圖標,

LPCTSTRIpIconName//IpIconName圖標資源名或系統(tǒng)預(yù)定義圖標標識名。)

LoadCursor:作用是在應(yīng)用程序中加載一個窗I」光標。其原型為:

HCURSORLoadCursor(HINSTANCEhlnstance,//hlnstance光標資源所在的模塊句柄,NULL則使用系

〃統(tǒng)預(yù)定義光標

LPC1STRIpCursorName)//IpCursorName光標資源名或系統(tǒng)預(yù)定義光標標識

〃名

GctStockObject:作用是獲取系統(tǒng)提供的背景刷,其原型為:

HBRUSHGetStockObject(intnBrush)://nBrush刷子的類型

(b)注冊窗口類

Win系統(tǒng)本身提供部分預(yù)定義的窗口類,程序員也可以自定義窗口類,窗口類必須先注冊后使用。

窗口類的注冊由函數(shù)RegisterClass()實現(xiàn)。

RegisterClass(&wndclass);//wndclass為窗口類結(jié)構(gòu)RegisterClass函數(shù)的返回為布爾值,注

〃冊成功則返回真

(C)創(chuàng)建窗口實例

創(chuàng)建一個窗口類的'實例由函數(shù)CreateWindow()實現(xiàn),函數(shù)原型如下:

HWNDCroateWindow

(LPCTSTRIpszClassName,〃窗口類名

LPCTSTRIpszTitle,〃窗口標題名

DWORDdwStyle,〃創(chuàng)建窗口的樣式

intx,y,〃窗口左上角坐標

intnWidth,nlleight.〃窗口寬度和度高

HWNDhwndParent,〃該窗口的父窗口句柄

HWENUhMcnu,〃窗口主菜單句柄

HINSTANCEhlnstance,〃創(chuàng)建窗口的應(yīng)用程序當前句柄

LPVOIDIpParam〃指向一個傳遞給窗口的參數(shù)值的指針

)

常用窗口樣式

few說明

WS_BORDER創(chuàng)信一帶邊框的窗口

WSCAPTION包犍一用標題欄的窗口

WS_VSCROLL創(chuàng)犍一帶垂直濠動條的窗口

WS_MAXIMIZEBOX包健一帶最大化框的窗口

WS_MAXIMIZE色犍一最大尺寸的窗口

WS_MINIMIZEBOX創(chuàng)犍一帶最小化框的窗口

WS_MINIMIZE創(chuàng)康一最小尺寸的窗口

WS_OVERLAPPED您犍一帶邊框和標題的窗口

WS_OVERLAPPEDWINDOW自犍一帶邊框、標題欄、系統(tǒng)菜單及最大、

最小化糖的窗口

WS_POPUP包犍一彈出式窗口

WS_POPUPWINDOW包犍一帶邊框和系統(tǒng)菜單的彈出式窗口

WS_SYSMENU打犍一帶系統(tǒng)菜單的曾口

WS_HSCROLL創(chuàng)屣一帶水平滾動條的菜單

(d)顯示窗口

窗口類的顯示由ShowWindow和UpdateWindow函數(shù)實現(xiàn)。應(yīng)用程序調(diào)用ShowWindow函數(shù)在屏幕上

顯不窗口:

ShowWindow(hwnd,nCmdshow);//nCmdshow為窗口顯示形式標識

sw_HIDE隱意窗口

sw_SHOWNORMAL顯示并激活窗口

sw_SHOWMINIMIZE顯示并最小化窗口

sw_SHOWMAXMIZE顯示并最大化窗口

sw_?HOWNOACTIVE顯示但不激活窗口

sw.RESTORE恢復(fù)窗口的原來位置及尺寸

顯示窗口后,應(yīng)用程序調(diào)用UpdateWindow更新并繪制用戶區(qū),并發(fā)出WM/AINT消息。

UpdatcWindow(hwnd);

(3)消息循環(huán)

消息循環(huán)的過程如下圖所示:

將消息傳遞給

窗口函數(shù)的相

Windo”不將

產(chǎn)生的消息

消息循環(huán)的常見格式如下:

MSGMsg;

while(GetMessage(&Msg,NULL,0,0))〃從消息隊列中讀取一條消息,并將消息放在MSG結(jié)構(gòu)中

{TranslateMcssage(&Msg);//將消息的虛擬鍵轉(zhuǎn)換為字符信息

DispeitchMessage(&Msg);"/將消息傳送到指定窗口函數(shù)

其中函數(shù)GetMessage形式為:

GetMessage

IpMSG,〃指向MSG結(jié)構(gòu)的指針

hwnd,

nMsgFilteMin,〃用于消息過濾的最小消息號值

nMsgFilterMax〃用于消息過濾的最大消息號值

)

返回零值,即檢索到WM_QUIT消息,程序結(jié)束循環(huán)并退出

2.窗口函數(shù)WinProc

WinProc定義了應(yīng)用程序?qū)邮盏降牟煌⒌捻憫?yīng),包含了對各種可能接收到的消息的處理過程。

WinProc函數(shù)由一個或多個switch語句組成。每一條case語句對應(yīng)一種消息,當應(yīng)用程序接收到一

個消息時,相應(yīng)的case語句被激活并執(zhí)行相應(yīng)的響應(yīng)程序模塊。

窗口函數(shù)的一般形式如下:

LRESULTCALLBACKWndProc(HWNDhwnd,LINTmessgae,WPARAMwParam,LPARAMIParam)

{…

switch(message)〃message為標識的消息

{case???

???

break;

caseWMDESTROY:

PostQuitMessage(0);

default:

returnDefWindowProc(hwnd,message,wParam,1Param);

)

return(0);

}

在消息處理程序段中一般都有對WM_DESTROY的處理,該消息是關(guān)閉窗口時發(fā)出的。它向應(yīng)用程序發(fā)

出刑LQUIT消息,請求退出處理函數(shù):

voidPostQuitMcssage(intnExitCode)〃nExitCodc為應(yīng)用程序的退出,為未定義處理過程的

〃消息提供缺省處理

3.數(shù)據(jù)類型

在Windows』中定義了Windows應(yīng)用程序中包含種類繁多的數(shù)據(jù)類型

則頻說明

WORD16位無符號整數(shù)

LONG32位有符號整數(shù)

DWORD32位無符號整數(shù)

HANDLE句柄

VINT32位無符號整數(shù)

BOOL布爾值

LPTSTR指向字符串的32位指針

LPCTSTR指向字符串常量的32位指針

4.一些重要的數(shù)據(jù)結(jié)構(gòu)

MSG:包含一個消息的全部信息,是消息發(fā)送的格式

WINDCLASS:包含一個窗口類的全部信息及屬性

POINT:定義了屏幕上或窗口中的一個點的X和Y坐標

RECT:定義了一個矩形區(qū)域及其左上角和右下角的坐標

五、應(yīng)用程序

【例2-1】創(chuàng)建應(yīng)用程序框架。本例的FI的在于說明創(chuàng)建Windows應(yīng)用程序的方法及過程,程序的效

果如下圖所示。

#include<windows.h>//包含應(yīng)用程序中所需的數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu)的定義

LRESULTCALLBACKWndProc(HWND.UINT,WPARAM,LPARAM);〃窗口函數(shù)說明

//----------以下初始化窗口類-----------------

intWINAPIWinMain(HINSTANCEhlnstance,

H1NSTANCEhPrcvInst,LPSTRIpszCmdLnCmdShow)

HWNDhwnd;

MSGMsg;

WNDCLASSwndclass;

charIpszClassName」="窗口";〃窗口類名

charlpszTitle[]="My_Windo\vs";〃窗口標題名

〃窗口類的定義

wndclass.style=O;〃窗口類型為缺省類型

wndclass.lpfnWndProc=WndProc;〃定義窗口處理函數(shù)

wndclass.cbClsExtra=O;〃窗口類無擴展

wndclass.cbWndExtra=O;〃窗口實例無擴展

wndclass.hlnstance=hlnslance;〃當前實例句柄

wndclass.hIcon=LoadIcon(NULLJDI_APPLICATION);〃窗口的最小化圖標為缺省圖標

wndclass.hCursor二LoadCursor(NULL,IDC_ARROW);〃窗口采用箭頭光標

wndclass.hbrBackground=GetStockObject(WHITE_BRUSH);//窗口背景為白色

wndclass.lpszMcnuNamc=NULL;//窗II中無菜單

wndclass.lpszClassName=lpszClassName;〃窗口類名為"窗口"

//..........以下進行窗口類的注冊……

if(!RegisierClass(&wndclass))〃如果注冊失敗則發(fā)出警告

{MessageBeep(O);

returnFALSE;}

//-----------創(chuàng)建窗口

hwnd=CrcateWindow

IpszClassName,〃窗口類名

IpszTitle,〃窗口實例的標題名

WS_OVERLAPPEDWINDOW,〃窗口的風(fēng)格

C\V_USEDEFAULT,

CW_USEDEFAULT.〃窗口左上角坐標為缺省值

CWJJSEDEFAULT,

CW_USEDEFAULT.,〃窗口的高和寬為缺省值

NULL,〃此窗口無父窗口

NULL,〃此窗口無主菜單

hlnstance,〃創(chuàng)建此窗口的應(yīng)用程序的當前句柄

NULL//不使用該值

);

//----------顯示窗口-

ShovvWindow(hwnd,nCmdShow);

//.........繪制用戶區(qū)................

UpdateWindow(hwnd);

//...........消息循環(huán)................

while(GctMessage(&Msg,NULL,0,()))

{

TranslatcMcssagc(&Msg);

DispatchMessage(&Msg);

I

returnMsg.wParam;〃消息循環(huán)結(jié)束即程序終止時將信息返回系統(tǒng)

I

〃窗口函數(shù)

LRESULTCALLBACKWndProc

(HWNDhwnd,

UINTmessage,

WPARAMwPaiam,

LPARAMIParam

switch(message)

{caseWM_DESTROY:

PostQuitMessage(O);

default:〃缺省時采用系統(tǒng)消息缺省處理函數(shù)

returnDef'Windo\vProc(hwnd,message,wParani,IParam);

relurn(O);

)

六、繪圖函數(shù)

在Windows平臺下,常用的繪圖函數(shù)有:

SetPixel:在x,y點畫上相應(yīng)的顏色。例如:SetPixel(hdc,x,y,crColor),crColor的類型是

COLORREF,COLORREF是一個32位的無符號整數(shù),代表一種顏色,常用RGB宏來生成顏色。

#defineRGB(r,g,b)((COLORREF)(((BYTE)(r)|\

((WORD)((BYTE)(g))?8))|\

((DWORD)((BYTE)(b))?16)))

MoveToEx:把當前點移彩到指定點,如MoveToEx(hdc,xBcg,yBcg,NULL);

LineTo:從當前點畫線到指定點,如LineTo(hdc,xEnd,yEnd);

當要畫圖時,應(yīng)在WM_PAINT消息下編寫程序:

switch(message)

{

caseWM_PAINT

hdc=BeginPaint(hwnd,&ps);

GetClientRect(hwnd.&rect);

…〃在此添加繪圖函數(shù)

EndPaint(hwnd.&ps);

return0;

caseWM_DESTROY:

PostQuitMessageiO);

default:〃缺省時采用系統(tǒng)消息缺省處理函數(shù)

returnDefWindowProc(hwnd.message,wParamJParam);

第二章計算機圖形學(xué)的實驗

2.1直線的生成

(-)直線的DDA算法

1、實驗?zāi)康?/p>

(1)熟悉TurboC或在VisualC++開發(fā)環(huán)境,掌握在TurboC或在VisualC++環(huán)境下正行圖形程序設(shè)

計的基本方法。

(2)掌握直線的DDA算法

2、實驗內(nèi)容

根據(jù)輸入的直線的端點坐標畫出相應(yīng)的直線。

3、獨立圖形運行程序的建立

TurboC對于用initgraphO函數(shù)直接進行的圖形初始化程序,

在編譯和鏈接

時并沒有將相應(yīng)的驅(qū)動程序裝入到執(zhí)行程序,當程序進行到intitgraphO

語句時,

再從該函數(shù)中第三個形式參數(shù)char*path中所規(guī)定的路徑中去找相應(yīng)的

驅(qū)動程序。若沒有驅(qū)動程序,則在C:\TC中去找,

如C:\TC中仍沒有或TC不存在,

將會出現(xiàn)錯誤:

BGIError:Graphics

notinitialized(use'initgraph')

因此,為了使用方便,

應(yīng)該建立一個不需要驅(qū)動程序就能獨立運行的可執(zhí)行

圖形程序,TurboC中規(guī)定用下述步驟(這里以EGA、VGA顯示器為例):

1.在C:\TC子目錄下輸入命令:BGIOBJEGAVGA

此命令將驅(qū)動程序EGAVGA.BGI轉(zhuǎn)換成EGAVGA.OBJ的目標文件。

2.

在C:\TC子目錄下輸入命令:TLIBLIB\GRAPHICS.LIB+EGAVGA

此命令的意思是將EGAVGA.OBJ的目標模塊裝到GRAPHICS.LIB庫文件中。

3.

在程序中initgraphO函數(shù)調(diào)用之前加上一句:

registei'bgidriver(EGAVGA_driver):

該函數(shù)告訴連接程序在連接時把EGAVGA的驅(qū)動程序裝入到用戶的執(zhí)行程序中。

經(jīng)過上面處理,編譯鏈接后的執(zhí)行程序可在任何目錄或其它兼容機上運行。

假設(shè)已作了前兩個步驟,若再向例6中加

registerbgidriver()函數(shù)則變成:

例7:

#include<stdio.h>

#include<graphics.h>

intmain()

(

intgdrivor=DETECT,gmodc;

registerbgidriver(EGAVGA_driver):/*建立獨立圖形運行程序*/

initgraph(gdriver,

gmode,〃c:\\tc");

bar3d(50,50,250,150,20:1);

getch();

closegraph();

return0;

)

上例編譯鏈接后產(chǎn)生的執(zhí)行程序可獨立運行。

4、參考程序

這里只給出了實現(xiàn)DDA算法的一個子函數(shù),當上機調(diào)試時需根據(jù)所選用的編程環(huán)境自己來成整個

程序。

#include<graphics.h>

#include<math.h>

#include<conio.h>

voidLine(intxO,intyO,intx1,irty1,intvalue)

{intx;

floatdx,dy,m,y;

dx=x1-x0;

dy=y1-yO;

m=dy/dx;

y=yo;

for(x=xO;x<=x1;x++)

{putpixel(x,(int)(y+0.5),value);

y=y+m;

if(getch()==17)exit();

)

)

voidmain()

{inii,driver,mode;

driver=DETECT;

registerbgidriver(EGAVGA_driver);

initgraph(&driver,&mode,"..\\bgi");

printf("pressanykeytocontinueexcpet'ctrl+Q'to

quitAn");

Line(100,100,500,400,15);

closegraph();

)

(二)直線的Breshenham算法

1、實驗?zāi)康?/p>

(1)熟悉TurboC或在VisualC++開發(fā)環(huán)境,掌握在TurboC或在VisualC++環(huán)境下正行圖形程序設(shè)

計的基本方法。

(2)掌握直線的Breshenham算法

2、實驗內(nèi)容

根據(jù)輸入的直線的端點坐標畫出相應(yīng)的直線。

3、參考程序

這里只給出了實現(xiàn)Breshenham算法的一個子函數(shù),當上機調(diào)試時需根據(jù)所選用的編程環(huán)境自己來

成整個程序。

voidline(x1,y1,x2,y2,c)

intx1,y1,x2,y2,c;

(

intdx;

intdy;

intx;

inty;

intp;

intconstl;

intconst2;

intinc;

inttmp;

dx=x2-x1;

dy=y2-y1;

if(dx*dy>=0)/*準備x或y的單位遞變值。*/

inc=1;

else

inc=-1;

if(abs(dx)>abs(dy)){

if(dx<0){

tmp=x1;/*將2a,3a象限方向*/

x1=x2;/*的直線變換至ij1a,4a*/

x2=tmp;

tmp=y1;/*象限方向去*/

y1=y2;

dx=-dy;

dy=-dy;

)

p=2*dy-dx;

constl=2*dy;/*注意此時誤差的*/

const2=2*(dy-dy);/*變化參數(shù)取值.*/

x=x1;

y=yi;

set_pixel(x,y,c);

while(x<x2){

x++;

if(P<0)

p+=const1;

else{

y+=inc;

p+=const2;

)

set_piexl(x,y,c);

)

)

else{

if(dy<0){

tmp=x1;/*將3b,4b象限方向的

*/

x1=x2;/*直線變換至U2b,1b*/

x2=tmp;/*象限方向去.*/

tmp-y1;

yi=y2;

dx="dy;

dy=-dy;

)

p=2*dx-dy;/*注意此時誤差的*/

const1=2*dx;/*變化參數(shù)取值.*/

const2=2*(dx-dy);

x=x1;

y=yi;

set_pixel(x,y,c);

while(y<y2){

y++;

if(P<0)

p+=const1;

else{

x+=inc;

p+=const2;

set_pixel(x,y,c);

)

)

}

2.2區(qū)域填充

1、實驗?zāi)康?/p>

(1)熟悉TurboC或在VisualC++開發(fā)環(huán)境,掌握在TurboC或在VisualC++環(huán)境下正行圖形程序設(shè)

計的基本方法。

(2)掌握多邊形的掃描線算法

2、實驗內(nèi)容

根據(jù)輸入的多邊形的頂點的坐標對?輸入多邊形進行填色。

3、參考程序

這里只給出了實現(xiàn)掃描線填色算法的子函數(shù),當上機調(diào)試時需根據(jù)所選用的編程環(huán)境自己來成整個

程序。

typedefstruct{

inty_top;

floatxjnt;

intdelta_y;

floaatx_changejDer_scan;

}EACH_ENTRY;

EACH_ENTRYSIDES[MAX_POINT];

intx[MAX_POINT],y[MAX_POINT];

intside_count,first_s,last_s,scan,bottomscan,x_int_count,r;

fill_area(count,x,y)

intcount,x[],y[];

{

sort_on_bigger_y(count);

first_s=1;

last_s=1;

for(scan=sides[1].y_top;scan>bottomscan?;scan--)

(

update_first_and_last(count,scan);

process_x_intersections(scan,first_s,last_s);

drawJines(scan,x_int_count,first_s);

update-_sides_list();

)

)

voidputjn_sid9sjist(entry,x1,y1,x2,y2,next_y);

intentry,x1,y1,x2,y2,next_y;

{

intmaxy;

floatx2_temp,x_change_temp;

x_change_temp=(float)(x2-x1)/(float)(y2-y1);

x2_temp=x2;/*以卡為退翁一點操作.*/

if((y2>y1)&&(y2<next_y)){

y2一;

x2_temp-=x_change_temp;

}

else{

if((y2<y1)&&(y2>next_y)){

y2++;

x2_temp+=x_change_temp;

)

)

/*以下為插入活性表操作.*/

maxy=(y1>y2)?y1:y2;

while((entry>1)&&(maxy>sides[entry-1].y_top))

{

sides[entry]=sides[entry?];

entry-

)

sides[entry].y_top=maxy;

sides[entry].delta_y=abs(y2-y1)+1;

if(yi>y2)

sides[entry].xjnt=x1;

else{

sides[entry].x_int=x2_temp;

sides[entry].

x_change_per_scan-x_change_temp;

)

voidsort_on_bigger_y(n)

intn;

(

intk,x1,y1;

side_count=0;

yi=y[n];

x1=x[n];

bottomscan=y[n];

for(k=1;k<n+1;k++)

(

if(yi!=y[k]){

side_count++;

putjn_sidesjist(side_count,x1,y1,x[k],

y[k]);

)

else{

move((short)xl,(short)yl);

line((short)x[k],(short)yl,status);

)

if(y[k]<bottomscan)bottomscan=y[k];

yi=y[k];xi=x[k];

)

)

voidupdate_first_and_last(count,scan)

intcount,scan;

(

while((sides[last_s+1].y_top>=scan)&&(last_s<count))

last_s++;

while(sides[first_s].delta_y==0)first_s++;

)

voidswap(x,y)

EACH_ENTRYx,y;

inti_temp;

floatf_temp;

i_temp=x.y_top;x.y_top=y.y_top;y.y_top=i_temp;

f_temp=x.xjnt;x.xjm=y.xjnt;y.x_int=f_temp;

i_temp=x.delta_y;x.delta=y.delta_y;y.delta_y=i_temp;

f_temp=x.x_change_per_scan;x,x_change_per_scan=y.

x_change_per_scan;y.x.

change_per_scan=f_temp;

)

voidsort_on_x(entry,first_s)

intentry,first_s;

(

while((entry>first_s)&&(sides[entry].xjnt<

sides[entry-1].xjnt))

{

swap(sides[entry],sides[entry-1]);

entry-

)

)

voidprocess_x_intersections(scan,firsts,last_s)

intscan,first_s,last_s;

{

intk;

x_int_cout=0;

for(k=first_s;k<last_s+1;k++)

{~~

if(sides[k],delta_y>0){

x_int_count++;

sort_on_x(k,first_s);

)

)

)

voiddraw_lines(scan,xjnt_count,index)

intscan,x_int_count,index;

{

intk,x,x1,x2;

for(k=1;k<(int)(x_int_count/2+1.5);k++)

(

while(sides[index].delta_y==0)index++;

x1=(int)(sides[index].xjnt+0.5);

index++;

while(sides[index].delta_y==0)index++;

x2=(int)(sides[index],xjnt+0.5);

move((short)x1,(short)scan);

Iine((short)x2,(short)scan,status);

index++;

)

)

voidupdate_sides_list()

(

intk;

for(k=first_s;k<last_s+1;k++)

(

if(sides[k].delta_y>0)

{

sides[k].delta_y-

sides[k].xjnt-=sides[k].

x_change_per_scan;

)

)

)

2.3直線的裁剪

1、實驗?zāi)康?/p>

(1)熟悉TurboC或在VisualC++開發(fā)環(huán)境,掌握在TurboC或在VisualC++環(huán)境下正行圖形程序設(shè)

計的基本方法.

(2)掌握Cohen-Sutherlard直線裁剪算法

2、實驗內(nèi)容

輸入多邊形頂點的坐標和待裁剪的直線的端點坐標,由多邊形對真線進行裁剪。

3、參考程序

這里只給出了實現(xiàn)Cohen-Sutherland直線裁剪算法的子函數(shù),當上機調(diào)試時需根據(jù)所選用的編程

環(huán)境自己來成整個程序。

clip_a_line(x1,y1,x2,y2,xw_min,xw_max,yw_min,yw_max)

intx1,x2,y1,y2;xw_min,xw_max,yw_min,yw_max;

{

inti,code1[4],code2[4],done,display;

floatm;

intx11,x22,y11,y22,mark;

done=0;

display=0;

while(done==0)

x11=x1;x22=x2;y11=y1;y22=y2;

encode(x1,y1,codel,xwmin,xwmax,ywmin,

yw_max);

encode(x2,y2,code2,xw_min,xw_max,yw_min,

yw_max);

if(accept(code1,code2))

{

done=1;

display=1;

break;

)

else

if(reject(codel,code2)i

{

done=1;

break;

)

mark=swap_if_needed(code1,code2);

if(mark==1)

(

x1=x22;

x2=x11;

y1=y22;

y2=y11;

)

if(x2==x1)m=-1;

else

m=(float)(y2-yl)/(float)(x2-x1);

if(codel[0])

(

x1+=(yw_min-y1)/m;

y1=yw_min;

)

elseif(codel[1])

(

x1-=(y1-yw_maxi/m;

y1=yw_max;

)"

elseif(codel[2])

(

y1-=(x1-xw_min)*m;

x1=xwmin;

)

elseif(code[3])

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論