計(jì)算機(jī)圖形學(xué)實(shí)驗(yàn)課實(shí)驗(yàn)報(bào)告總_第1頁(yè)
計(jì)算機(jī)圖形學(xué)實(shí)驗(yàn)課實(shí)驗(yàn)報(bào)告總_第2頁(yè)
計(jì)算機(jī)圖形學(xué)實(shí)驗(yàn)課實(shí)驗(yàn)報(bào)告總_第3頁(yè)
計(jì)算機(jī)圖形學(xué)實(shí)驗(yàn)課實(shí)驗(yàn)報(bào)告總_第4頁(yè)
計(jì)算機(jī)圖形學(xué)實(shí)驗(yàn)課實(shí)驗(yàn)報(bào)告總_第5頁(yè)
已閱讀5頁(yè),還剩152頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

西南交通大學(xué)信息科學(xué)與技術(shù)學(xué)院

計(jì)算機(jī)圖形學(xué)實(shí)驗(yàn)課

(2015?2016學(xué)年第H學(xué)期)

實(shí)

驗(yàn)

報(bào)

學(xué)號(hào):20132184姓名:朱彥榮

專(zhuān)業(yè):軟件工程班級(jí):軟件工程2

第1頁(yè)共1頁(yè)

第2頁(yè)共2頁(yè)

課程名稱(chēng)計(jì)算機(jī)圖形學(xué)

班級(jí)軟件工程2學(xué)號(hào)20132184姓名朱彥榮

實(shí)驗(yàn)日期2016/3/23實(shí)驗(yàn)成績(jī)

實(shí)驗(yàn)名稱(chēng)實(shí)驗(yàn)一、鍵盤(pán)與鼠標(biāo)按鍵消息處理實(shí)驗(yàn)

1.實(shí)驗(yàn)?zāi)康?/p>

熟悉集成開(kāi)發(fā)環(huán)境和編輯操作,了解外圍設(shè)備的工作原理,根據(jù)設(shè)備特征和

產(chǎn)生的消息信號(hào)處理消息,管理設(shè)備。

2.實(shí)驗(yàn)設(shè)備

設(shè)備編號(hào)設(shè)備名稱(chēng)數(shù)量

1鼠標(biāo)1

2鍵盤(pán)1

3主機(jī)1

4顯示器1

5網(wǎng)線(xiàn)1

第3頁(yè)共3頁(yè)

3.實(shí)驗(yàn)設(shè)計(jì)過(guò)程說(shuō)明

軟件設(shè)計(jì)工具名稱(chēng):__________VC++6.0____________________

實(shí)驗(yàn)內(nèi)容:

①在鍵盤(pán)上進(jìn)行按鍵操作,如果是可顯示字符,在屏幕上輸出對(duì)應(yīng)的ASCII

碼;

②點(diǎn)擊鼠標(biāo)左鍵,在屏幕上的客戶(hù)區(qū)窗口中鼠標(biāo)點(diǎn)擊的位置,輸出一提示

字符串。

設(shè)計(jì)過(guò)程:

在VC++6.0中建立Win32Applicaption,然后在消息處理機(jī)制中添加相應(yīng)的

處理事件,點(diǎn)擊運(yùn)行即可;

基本工作原理:

該實(shí)驗(yàn)的核心就是消息處理。消息,來(lái)自于事件(event),我們的所有操作無(wú)

外乎是對(duì)事件的處理。任何大的事件總能不斷細(xì)分成很多個(gè)基本事件,而基本事

件依據(jù)與硬件設(shè)備輸入設(shè)備的不同而增加。比如“點(diǎn)擊鼠標(biāo)左鍵”這個(gè)事件就會(huì)

產(chǎn)生相應(yīng)的消息,我們要做的就是對(duì)消息的處理了。根據(jù)上面的論證,我們可以

很輕松的理解這一環(huán)境編程的核心。當(dāng)用戶(hù)在窗口上按下一個(gè)字符鍵,程序?qū)⒌?/p>

到一條WMJZHAR消息,在其wParam參數(shù)中含有字符的碼值,該消息包含了可

顯示字符的百值。當(dāng)用戶(hù)按下鼠標(biāo)左鍵,將產(chǎn)生WM_LBUTTONDOWN消息,可

以根據(jù)這些消息特征編寫(xiě)消息處理函數(shù),并在窗口中輸出對(duì)應(yīng)的文字信息,管理

設(shè)備。

設(shè)計(jì)步驟:

建立工程->編寫(xiě)消息處理函數(shù)-〉運(yùn)行程序,觀察結(jié)果

第4頁(yè)共4頁(yè)

#include<windows.h>

#include<stdio.h>

LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);

charszTitle口二〃SimpleProgramforWindows/7;//title

intAPIENTRYWinMain(HINSTANCEhlnstance,//applicationprograminstancehandle

HINSTANCEhPrelnst,//theprograminstanceprevioushandle

LPSTRIpszCmdLine,//Commandlineparameterstring

intnCmdShow)//theprogrambeginninghowtoshowwindow

(

HWNDhWnd;

MSGmsg;

WNDCLASSwcGRF;

if(IhPrelnst)

(

〃若hPelnst為零,則說(shuō)明正運(yùn)行的這個(gè)實(shí)例是程序的第一個(gè)實(shí)例,

〃僅當(dāng)運(yùn)行第一個(gè)實(shí)例時(shí);需要注冊(cè)窗口類(lèi)(對(duì)16位程序而言)

〃注冊(cè)窗口類(lèi)如下:

wcGRF.IpszClassName=szTitle;〃窗口類(lèi)的類(lèi)名

第5頁(yè)共5頁(yè)

wcGRF.hlnstance=hlnstance;〃定義該類(lèi)的應(yīng)用程序的句柄

wcGRF.IpfnWndProc=WndProc;〃窗口函數(shù)

wcGRF.hCursor=LoadCursor(NULL,IDCCROSS);//光標(biāo)對(duì)象的句柄

wcGRF.hlcon=LoadIcon(NULL,IDIAPPLICATION);〃圖標(biāo)對(duì)象的句柄

wcGRE.IpszMenuName=NULL;〃標(biāo)識(shí)菜單對(duì)象的字符串

wcGRF.hbrBackground=(HBRUSH)::GetStockObject(WHITE_BRUSH);

//usedtoclearhandle

wcGRF.style=CS_HREDRAW|CS_VREDRAW;//windowsstyle;

wcGRF.cbClsExtra=0;〃類(lèi)變量占據(jù)的存儲(chǔ)空間

wcGRF.cbWndExtra=0;〃實(shí)例變量占用的存儲(chǔ)空間

if(!RegisterClass(&wcGRF))//如注冊(cè)失敗則返回

returnFALSE;

)

//對(duì)每個(gè)實(shí)例創(chuàng)建一個(gè)窗口對(duì)象

hWnd=CreateWindow(szTitle,〃類(lèi)名,指定該窗口所屬的類(lèi)

szTitle,〃窗口名,即在標(biāo)題欄顯示的文本

WSOVERLAPPEDWINDOW,

//窗口風(fēng)格,以下四個(gè)參數(shù)確定窗口初始位置及大小

30,〃窗口左上角相對(duì)屏幕的X坐標(biāo)

30,〃窗口左上角相對(duì)屏幕的Y坐標(biāo)

540,〃窗口寬度

360,〃窗口高度

第6頁(yè)共6頁(yè)

NULL,〃父窗口句柄

NULL,〃菜單句柄

hlnstance,〃實(shí)例句柄

NULL);〃額外參數(shù)

ShowWindow(hWnd,nCmdShow);

UpdateWindow(hWnd);

〃消息循環(huán)

while(GetMessage(&msg,NULL,0,0))〃從應(yīng)用程序隊(duì)列中取出?條消息

(

TranslateMessage(&msg);〃翻譯消息

DispatchMessage(&msg);〃發(fā)送消息

)

return(msg.wParam);

}

LRESULTCALLBACKWndProc(HWNDhWnd,UINTMsg,WPARAMwParam,LPARAMIParam)

{

HDChDC;

switch(Msg)

!

caseWM_CHAR:

charstr[40];

第7頁(yè)共7頁(yè)

sprintf(str,z/thecharcodeisHEX:%xHDEC:%d,z,wParam,wParam);

MessageBox(hWnd,str,,zKeyBoardkeypressTest”,MB_OKCANCEL);

break;

caseWMLBUTTONDOWN:

MessageBox(hWnd,^mouseclick","MousePress”,MB_OK);

hDC=GetDC(hWnd);

TextOut(hDC,LOWORD(lParam),HIWORD(lParam),z,clickmouseleft

strlenCclickmouseleft〃));

ReleaseDC(hWnd,hDC);

break;

caseWM_CLOSE:

if(IDOK二二MessageBox(NULL,“真的要退出嗎?〃,〃WindowClose

〃,MB_OKCANCEL|MB_ICONQUESTION))

i

DestroyWindow(hWnd);

}

break;

caseW.PAINT:

PAINTSTRUCTps;

hDC=BeginPaint(hWnd,&ps);〃在WMPAINT里必須用這個(gè)函數(shù)

TextOut(hDC,0,0,〃MouseLeftButtonandKeyTest”,strlen(z,MouseLeft

ButtonandKeyTest"));

EndPaint(hWnd,&ps);

break;

caseWMDESTROY:

第8頁(yè)共8頁(yè)

PostQuitMessage(0);

break;

default:

return(DefWindowProc(hWnd,Msg,wParam,1Param));

}

return0;

}

/*

LRESULTCALLBACKWndProc(HWNDhWnd,UINTmessg,WPARAMwParam,LPARAM1Param)

(

HDChdc;

PAINTSTRUCTps;

RECTrect;

switch(messg)

(

caseWM_PAINT:

hdc=BeginPaint(hWnd,&ps);

GetClientRect(hWnd,&rect);

DrawText(hdc,"Hello,朱彥榮?。?!〃,-1,&rect,DT_CENTER|DT_VCENTER);

EndPaint(hWnd,&ps);

第9頁(yè)共9頁(yè)

return0;

caseWM_DESTR0Y:

PostQuitMessage(0);

return(0);

)

returnDefWindowProc(hWnd,messg,wParam,1Param);

}*/

執(zhí)行順序:

消息的分派和處理

實(shí)驗(yàn)結(jié)果記錄:

單擊鼠標(biāo)左鍵:

點(diǎn)擊確定后:

clickmouseleft

第10頁(yè)共10頁(yè)

在鍵盤(pán)上點(diǎn)擊a得到的結(jié)果:

4.實(shí)驗(yàn)結(jié)果的分析和描述

由實(shí)驗(yàn)的內(nèi)容和環(huán)境可以知道,該實(shí)驗(yàn)的核心就是消息處理。說(shuō)起消息處理,

這是模仿人類(lèi)社會(huì)工作方式的一種仿真模式。消息,來(lái)自于事件(event),我們

的所有操作無(wú)外乎是對(duì)事件的處理。任何大的事件總能不斷細(xì)分成很多個(gè)基本事

件,而基本事件依據(jù)與硬件設(shè)備輸入設(shè)備的不同而增加。比如“點(diǎn)擊鼠標(biāo)左鍵”

這個(gè)事件就會(huì)產(chǎn)生相應(yīng)的消息,我們要做的就是對(duì)消息的處理了。根據(jù)上面的論

證,我們可以很輕松的理解這一環(huán)境編程的核心。

核心代碼分析:

這個(gè)實(shí)驗(yàn)主要是兩個(gè)輸入設(shè)備上的測(cè)試,首先是鍵盤(pán),當(dāng)我們按下鍵盤(pán)上的一

個(gè)鍵時(shí),會(huì)經(jīng)過(guò)很復(fù)雜的過(guò)程,比如8042、8048等硬件最終將按下鍵的make,

break碼等傳入緩沖區(qū)中,并且在此程序中會(huì)產(chǎn)生WM_CHAR這一消息,我們要

做的就是對(duì)這個(gè)消息的處理了,很簡(jiǎn)單的,操作系統(tǒng)已經(jīng)為我們屏蔽了很多的細(xì)

節(jié)。同樣,點(diǎn)擊鼠標(biāo)也是同樣的道理,不再一一贅述了。

實(shí)驗(yàn)結(jié)果的分類(lèi):點(diǎn)擊鼠標(biāo),彈出對(duì)話(huà)框;按下按鍵,彈出對(duì)話(huà)框。

各個(gè)主要組成部分的說(shuō)明:主要是消息處理的代碼。

存在的問(wèn)題:功能簡(jiǎn)陋

可以改進(jìn)的方面和建議:可以添加更加復(fù)雜的消息處理事件,使得整個(gè)程序更加

系統(tǒng)化。

第11頁(yè)共11頁(yè)

第12頁(yè)共12頁(yè)

課程名稱(chēng)計(jì)算機(jī)圖形學(xué)

班級(jí):軟件工程2學(xué)號(hào):20132184姓名:朱彥榮

實(shí)驗(yàn)日期:2016/3/30實(shí)驗(yàn)成績(jī):

實(shí)驗(yàn)名稱(chēng):實(shí)驗(yàn)二、窗口移植與簡(jiǎn)單圖案繪制實(shí)驗(yàn)

1.實(shí)驗(yàn)?zāi)康?/p>

掌握計(jì)算機(jī)圖形學(xué)編程實(shí)現(xiàn)最基本的圖形程序的步驟和方法.

2.實(shí)驗(yàn)設(shè)備

設(shè)備編號(hào)設(shè)備名稱(chēng)數(shù)量

1鼠標(biāo)1

2鍵盤(pán)1

3主機(jī)1

4顯示器1

5網(wǎng)線(xiàn)1

第13頁(yè)共13頁(yè)

3.實(shí)驗(yàn)設(shè)計(jì)過(guò)程說(shuō)明

軟件設(shè)計(jì)工具名稱(chēng):_________VC++6.0___________________

實(shí)驗(yàn)內(nèi)容:窗口移植與簡(jiǎn)單圖案繪制

設(shè)計(jì)過(guò)程:編寫(xiě)程序->編譯運(yùn)行->逐步迭代改進(jìn)->得出結(jié)果

基本工作原理:

這次的實(shí)驗(yàn)?zāi)康氖亲屛覀兏玫睦斫饪蚣芎褪褂美L圖函數(shù),因此繪圖的原理

很簡(jiǎn)單。

設(shè)計(jì)步驟:編寫(xiě)程序->編譯運(yùn)行->逐步迭代改進(jìn)->得出結(jié)果

voidCPaint_simp1e_graphicsView::OnDraw(CDC*pDC)

(

CPaint_simp1e_graphicsDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

//TODO:adddrawcodefornativedatahere

〃建立畫(huà)筆

CPenpen_Zuobixi;

第14頁(yè)共14頁(yè)

pen_Zuobixi.CreatePen(PS_SOLID,4,RGB(0,0,0));

pDC->SelectObject(&pen_Zuobixi);

〃指定原點(diǎn)

pDC->SetViewportOrg(100,255);

pDC->SetTextColor(RGB(255,0,0));

〃繪制橫坐標(biāo)

CStringsPIText□={〃一1/2兀〃/〃,〃:1/2?!ǎㄘ!?,〃3/2”〃,〃2?!?,〃5/2兀

〃,〃3?!?,〃7/2?!ǎ??!?,〃9/2兀〃,〃5n〃};

intn="l;

intnTemp=0;

while(nTemp<=660)

(

pDC->LineTo(60*n,0);

pDC->LineTo(60*n,-5);

pDC->MoveTo(60*n,0);

pDC->TextOut(60*n-sPIText[n+1].GetLength()*3,16,sPIText[n+1]);

n++;

nTemp+=60;

}

pDC->MoveTo(0,0);

CStringstrTemp;

〃繪制縱坐標(biāo)

for(n=-4,nTemp=0;nTemp<=180;n++,nTemp+=60)

第15頁(yè)共15頁(yè)

pDC->LineTo(0,60*n);

pDC->LineTo(5,60*n);

pDC->MoveTo(0,60*n);

strTemp.Format(〃%d〃,-n);

pDC->TextOut(10,60*n,strTemp);

)

doubley,radian;

for(intx=-60;x<600;x++)

(

〃弧度二X坐標(biāo)/曲線(xiàn)寬度*角系數(shù)*n

//Y坐標(biāo)二振幅*曲線(xiàn)寬度*sin(弧度)

radian=x/((double)60*2)*PI;

y=sin(radian)*2*60;

pDC->MoveTo((int)x,(int)y);

pDC->LineTo((int)x,(int)y);

)

pen_Zuobixi.DeleteObject();

)

執(zhí)行順序:當(dāng)程序運(yùn)行的時(shí)候會(huì)自動(dòng)調(diào)用OnDraw()的內(nèi)容,程序就自動(dòng)執(zhí)行了。

實(shí)驗(yàn)結(jié)果記錄:

第16頁(yè)共16頁(yè)

4.實(shí)驗(yàn)結(jié)果的分析和描述

窗口移植,是窗口繪制代碼的一種移植。在MFC平臺(tái)下,我們可以自己搭建

相應(yīng)的窗口顯示環(huán)境,具體的方法比較固定。簡(jiǎn)單圖案的繪制,主要是考差了我

們繪制基本的圖案的能力,其中涉及了圖案的布局、計(jì)算、顯示等操作。在這里

我畫(huà)了一個(gè)正弦函數(shù)。

實(shí)驗(yàn)結(jié)果的分類(lèi):繪圖類(lèi)、窗口移植類(lèi)

各個(gè)主要組成部分的說(shuō)明:繪圖的步驟,與當(dāng)前窗口的關(guān)聯(lián)。

存在的問(wèn)題:程序還是過(guò)于簡(jiǎn)單。

可以改進(jìn)的方面和建議:可以增加更多的繪圖元素,豐富視覺(jué)感受。

第17頁(yè)共17頁(yè)

第18頁(yè)共18頁(yè)

課程名稱(chēng)計(jì)算機(jī)圖形學(xué)

班級(jí)軟件工程2學(xué)號(hào)20132184姓名朱彥榮

實(shí)驗(yàn)日期2016/4/6實(shí)驗(yàn)成績(jī)

實(shí)驗(yàn)名稱(chēng)實(shí)驗(yàn)三、指針式橢圓形實(shí)時(shí)顯示時(shí)鐘設(shè)計(jì)實(shí)驗(yàn)

1.實(shí)驗(yàn)?zāi)康?/p>

掌握定時(shí)器的響應(yīng)處理方式,掌握簡(jiǎn)單繪圖函數(shù)的使用和應(yīng)用程序設(shè)計(jì)。

2.實(shí)驗(yàn)設(shè)備

設(shè)備編號(hào)設(shè)備名稱(chēng)數(shù)量

1鼠標(biāo)1

2鍵盤(pán)1

3主機(jī)1

4顯示器1

5網(wǎng)線(xiàn)1

第19頁(yè)共19頁(yè)

3.實(shí)驗(yàn)設(shè)計(jì)過(guò)程說(shuō)明

軟件設(shè)計(jì)工具名稱(chēng):___________VC++6.0___________________

實(shí)驗(yàn)內(nèi)容:利用消息映射與類(lèi)中對(duì)應(yīng)的成員函數(shù),設(shè)計(jì)一個(gè)指針式橢圓形實(shí)

時(shí)顯示時(shí)鐘。

設(shè)計(jì)過(guò)程:分析題目制定解決方案——>編寫(xiě)時(shí)鐘程序——>得出結(jié)論。

基本工作原理:每隔一段時(shí)間,定時(shí)器就會(huì)自動(dòng)調(diào)用重繪函數(shù)刷新屏幕,最終

畫(huà)出當(dāng)前時(shí)間對(duì)應(yīng)的時(shí)鐘。

設(shè)計(jì)步驟:分析題目制定解決方案——>編寫(xiě)時(shí)鐘程序——>得出結(jié)論。

單擊VIEW菜單的ClassWizard項(xiàng),在顯示的MFCClassWizard對(duì)話(huà)框中的Class

name選項(xiàng)中,選擇CTestView類(lèi);在Messages選項(xiàng)中,選中WM_TIMER消息,如圖所示,

目前WMTIMER消息還沒(méi)有相對(duì)應(yīng)的類(lèi)的成員函數(shù)。

第20頁(yè)共20頁(yè)

選中WM_TIMER消息單擊ADDFUNCTION按鈕,就會(huì)在該類(lèi)中添加與該消息對(duì)應(yīng)的成員

函數(shù)。本例中,為W_TIMER消息在類(lèi)中添加了對(duì)應(yīng)的成員函數(shù)OnTimer,如圖所示。

添加類(lèi)中與消息對(duì)應(yīng)的成員函數(shù)單擊EditCode按鈕,可以看到系統(tǒng)已經(jīng)自動(dòng)生成了處理

WMJIMER消息所對(duì)應(yīng)的函數(shù)OnTimer所需的基本代碼。

對(duì)于每個(gè)成員函數(shù),在需要修改的函數(shù)中找到的注釋語(yǔ)句“〃TODO”之下,再添加所

第21頁(yè)共21頁(yè)

需要的應(yīng)用代碼就可以達(dá)到各自應(yīng)用的目標(biāo)了,函數(shù)OnTimer修改后的相應(yīng)代碼如下:

voidCTestView::0nTimer(UINTnlDEvent)

InvalidateRect(NULL,true);〃更新繪圖區(qū)

UpdateWindow();〃更新窗口區(qū)

CView::OnTimer(nlDEvent);

}

然后,在OnDrawO中添加代碼如下:

voidCMyView::OnDraw(CDC*pDC)

(

CMyDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

//TODO:adddrawcodefornativedatahere

〃獲取客戶(hù)區(qū)

RECTRect;

GetClientRect(&Rect);

〃計(jì)算橢圓中心位置

intCenterX=Rect.right/2;

intCenterY=Rect.bottom/2;

〃取當(dāng)前時(shí)間

CTimeTime=CTime::GetCurrentTime();

CStringstr;

inti,x,y;

CSizesize;

第22頁(yè)共22頁(yè)

CPenPen2(PS_SOIJD,10,RGB(123,60,64));

〃先記下以前的畫(huà)筆,再設(shè)置當(dāng)前畫(huà)筆

CPen*01dPen2=pDC->Select0bject(&Pen2);

pDC->Ellipse(5,5,Rect.right-5,Rect.bottom-5);

〃創(chuàng)建一支黑色的筆,用來(lái)畫(huà)橢圓

CPenPen(PS_S0LID,20,RGB(3,234,64));

〃先記下以前的畫(huà)筆,再設(shè)置當(dāng)前畫(huà)筆

CPen*01dPen=pDC->SelectObject(&Pen);

//繪制鐘面橢圓

pDC->Ellipse(20,20,Rect.right_20,Rect.bottom-20);

CPenPenl(PS_S0LID,3,RGB(3,3,64));

〃先記下以前的畫(huà)筆,再設(shè)置當(dāng)前畫(huà)筆

CPen*01dPenl=pDC->SelectObject(SPenl);

pDC->Ellipse(20,20,Rect.right-20,Rect.bottom-20);

doubleRadians;

〃設(shè)置字體顏色為黑色

pDC->SetTextColor(RGB(0,0,0));

for(i=l;i<=12;i++){

〃格式化鐘點(diǎn)值

str.Format("%d”,i);

size=pDC->GetTextExtent(str,str.GetLengthO);

Radians=(double)i*6.28/12.0;

〃計(jì)算鐘點(diǎn)放置的位置

x=CenterX-(size,cx/2)+(int)((double)(CenterX-20)*

第23頁(yè)共23頁(yè)

sin(Radians));

y=CenterY-(size.cy/2)-(int)((double)(CenterY-20)*

cos(Radians));

〃繪制鐘點(diǎn)

pDC->TextOut(x,y,str);

)

〃計(jì)算時(shí)鐘指針的夾角

Radians=(double)Time.GetHour()+(double)Time.GetMinute()/60.0+

(double)Time.GetSecond()/3600.0;

Radians*=6.28/12.0;

〃創(chuàng)建時(shí)鐘指針畫(huà)筆

CPenHourPen(PS_S0LID,5,RGB(255,255,0));

pDC->SelectObject(&HourPen);

〃繪制時(shí)鐘指針

pDC->MoveTo(CenterX,CenterY);

pDC->LineTo(CenterX+(int)((double)(CenterX/3)*sin(Radians)),

CenterY-(int)((double)(CenterY/3)*cos(Radians)));

〃計(jì)算分鐘指針的夾角

Radians=(double)Time.GetMinute()+(double)Time.GetSecond()/60.0;

Radians*=6.28/60.0;

〃創(chuàng)建分鐘指針畫(huà)筆

CPenMinutePen(PS_S0LID,3,RGB(255,0,255));

pDC->SelectObject(&MinutePen);

〃繪制分鐘指針

第24頁(yè)共24頁(yè)

pDC->MoveTo(CenterX,CenterY);

pDC->LineTo(CenterX+(int)((double)(CenterX*2)/3)*sin(Radians),

CenterY-(int)((double)(CenterY*2/3)*cos(Radians)));

〃計(jì)算秒鐘指針的夾角

Radians=(double)Time.GetSecondO;

Radians*=6.28/60.0;

〃創(chuàng)建秒鐘指針畫(huà)筆

CPenSecondPen(PS_SOLID,1,RGB(0,255,255));

pDC->SelectObject(&SecondPen);

〃繪制秒鐘指針

pDC->MoveTo(CenterX,CenterY);

pDC->LineTo(CenterX+(int)((double)(CenterX*4)/5)*sin(Radians),

CenterY-(int)((double)(CenterY*4)/5*cos(Radians)));

pDC->SelectObject(OldPen);

)

執(zhí)行J順序:編譯運(yùn)行后,定時(shí)器采用中斷方式不斷地刷新屏幕。

實(shí)驗(yàn)結(jié)果記錄:

第25頁(yè)共25頁(yè)

4.實(shí)驗(yàn)結(jié)果的分析和描述

設(shè)當(dāng)前需要顯示的時(shí)間為Hour時(shí)Minute分Second秒,則經(jīng)過(guò)簡(jiǎn)單計(jì)算就可

得到各個(gè)指針實(shí)時(shí)顯示夾角。計(jì)算依據(jù)為:

時(shí)鐘指針實(shí)時(shí)顯示的夾角:AHour=(Hour+Minute左0+Second/3600)*2n/12;

分鐘指針實(shí)時(shí)顯示的夾角:AMinute=(Minute+Second^O)*2”由0;

秒鐘指針實(shí)時(shí)顯示的夾角:ASecond=Second*2n/60;

時(shí)鐘的鐘面用橢圓形顯示,橢圓的中心位置可以確定在客戶(hù)窗口的顯示中心;繪

制時(shí)、分、針時(shí),用不同顏色的直線(xiàn)段顯示,長(zhǎng)度分別為橢圓半長(zhǎng)軸的3、羽、

奶;時(shí)鐘表面的時(shí)間刻度,可用角度劃分的方式均勻劃分成12份,并用1~12

的數(shù)字表示。時(shí)間的獲取方法:利用計(jì)時(shí)器的響應(yīng)函數(shù)處理,每秒鐘更新一次時(shí)

鐘畫(huà)面,重畫(huà)時(shí)鐘的各個(gè)指針,各指針的位置可以通過(guò)顯示夾角的計(jì)算得到,達(dá)

到實(shí)時(shí)顯示時(shí)鐘的目標(biāo)。

實(shí)驗(yàn)結(jié)果的分類(lèi):時(shí)鐘繪制類(lèi)、時(shí)間刷新類(lèi)。

各個(gè)主要組成部分的說(shuō)明:注意定時(shí)器的運(yùn)用o

第26頁(yè)共26頁(yè)

存在的問(wèn)題:可以讓始終更加美觀?點(diǎn)。

可以改進(jìn)的方面和建議:增加更多的設(shè)計(jì)理念美化時(shí)鐘。

第27頁(yè)共27頁(yè)

第28頁(yè)共28頁(yè)

課程名稱(chēng)計(jì)算機(jī)圖形學(xué)

班級(jí)軟件工程2學(xué)號(hào)20132184姓名朱彥榮

實(shí)驗(yàn)日期2016/4/13實(shí)驗(yàn)成績(jī)

實(shí)驗(yàn)名稱(chēng)實(shí)驗(yàn)四、計(jì)算機(jī)圖形學(xué)直線(xiàn)與圓的基本繪圖算法實(shí)驗(yàn)

1.實(shí)驗(yàn)?zāi)康?/p>

本節(jié)主要講述如何在指定的輸出設(shè)備(如光柵圖形顯示器)上利用點(diǎn)構(gòu)造其他

基本二維幾何圖形(如點(diǎn)、直線(xiàn)、圓、橢圓、多邊形域及字符串等)的算法與

原理,并利用VisualC++編程實(shí)現(xiàn)這些算法。

2.實(shí)驗(yàn)設(shè)備

設(shè)備編號(hào)設(shè)備名稱(chēng)數(shù)量

1鼠標(biāo)1

2鍵盤(pán)1

3主機(jī)1

4顯示器1

5網(wǎng)線(xiàn)1

第29頁(yè)共29頁(yè)

3.實(shí)驗(yàn)設(shè)計(jì)過(guò)程說(shuō)明

軟件設(shè)計(jì)工具名稱(chēng):____________VC++6.0____________________

實(shí)驗(yàn)內(nèi)容:直線(xiàn)與圓的基本繪圖算法___________________

設(shè)計(jì)過(guò)程:掌握原理——>轉(zhuǎn)換成計(jì)算機(jī)語(yǔ)言——>編寫(xiě)編譯運(yùn)行程序

基本工作原理:

畫(huà)直線(xiàn)算法:

(1)DDA(數(shù)值微分)算法

DDA算法原理:如圖4-1所示,已知過(guò)端點(diǎn)出(項(xiàng),%),。1?,)])的直線(xiàn)段PMi;

直線(xiàn)斜率為k=(yLyo)/(Xi-xo),從x的左端點(diǎn)X。開(kāi)

始,向x右端點(diǎn)步進(jìn)畫(huà)線(xiàn),步長(zhǎng)=1(個(gè)像素),計(jì)算

相應(yīng)的y坐標(biāo)y=kx+B;取像素點(diǎn)[x,round(y)]

作為當(dāng)前點(diǎn)的坐標(biāo)。

計(jì)算》+|=kxj+i+B=kx\+B+k&c=y\+kL

x,當(dāng)Ax=1,M+I=),,?+k,即當(dāng)x每遞增1,y遞增k(即直線(xiàn)斜率)。

注意分析:上述算法僅適用于^<1的情形。在這

第30頁(yè)共30頁(yè)

種情況下,X每增加l,y最多增加lo當(dāng)Z21時(shí),必圖4-1直線(xiàn)DDA算法掃描轉(zhuǎn)換

須把x,y地位互換,y每增加1,x相應(yīng)增加11k。

(2)直線(xiàn)的中點(diǎn)畫(huà)線(xiàn)法中點(diǎn)畫(huà)線(xiàn)法的基本原理如圖4-2所示。在畫(huà)直線(xiàn)段的過(guò)程中,

當(dāng)前像素點(diǎn)為P,下一個(gè)像素點(diǎn)有兩種選擇,點(diǎn)Pi或2。

M為Pi與P2中點(diǎn),Q為理想直線(xiàn)與X=X,+1垂線(xiàn)的交

點(diǎn)。當(dāng)M在。的下方時(shí),則上方的P2應(yīng)為下一個(gè)像素

點(diǎn);當(dāng)M在Q的上方時(shí),應(yīng)取下方的Pi為下一點(diǎn)。

中點(diǎn)畫(huà)線(xiàn)法的實(shí)現(xiàn):

令直線(xiàn)段為L(zhǎng)[po(Xo,yo),pGiji)],其方程式F(x,y)=ax+by+c=Q?

其中,-i,6=兩-沏,。=91一由加

點(diǎn)與L的關(guān)系如下:P=(xp,yp)在直線(xiàn)上,F(xiàn)(x,y)=0;

中點(diǎn)畫(huà)線(xiàn)法每步迭代

在直線(xiàn)上方,F(xiàn){x,y)>0;

在直線(xiàn)下方,F(xiàn)(x,y)<0。涉及的像素和中點(diǎn)示意圖把M代入尸(x,y),判斷F

的符號(hào),可知Q點(diǎn)在中點(diǎn)M的上方還是下方。為此構(gòu)造判別式d=F(M)=F(Xp+l,

為+0.5)=〃(而+1)+6(切+0.5)+c。當(dāng)4<0,UQ點(diǎn))在M上方,取P2為下一個(gè)像

素。當(dāng)d>0,L(Q點(diǎn))在M下方,取Pi為下一個(gè)像素。當(dāng)d=0,選4或尸2

均可,取P,為下一個(gè)像素。其中d是xp,y?的線(xiàn)性函數(shù)。

=mx+b,其中b-y\-mx\,m=(?-乃)/(工廠(chǎng)4)=dy/dx;此處的

討論直線(xiàn)方向限于第像限,如圖4-3所示,當(dāng)直線(xiàn)光柵化時(shí),x每次都增加1個(gè)單

元,設(shè)x像素為(如%)。下一個(gè)像素的列坐標(biāo)為8+1,行坐標(biāo)為y或者遞增1為》+1,

由y與4-3第一象限直線(xiàn)光柵化

第31頁(yè)共31頁(yè)

Bresenham算法:y,及y/+l的距離d\及d2的大小而定。

如果4-42>。,則M+i=M+l,否則M+i=M。將式(4.1)、(4.2)、(4.3)代入d\-dz,再

用dr乘等式兩邊,并以P,=3L"2)心代入上述等式,得

P,=2x,<iy-2y,dr+2dy+(2/?-l)dx(4.4)4-d2是用以判斷符號(hào)的誤差。由于在第一象限,

<h-總大于0,所以P,仍然可以用做判斷誤差的符號(hào)。PM為

Pi+1=P,-+2dy-2(yi+i-y,)dr(4.5)

求誤差的初值Pi,可將為、M和b代入式(4.4)中的毛、%,而得到

Pi=2dy-dx

綜合上面的推導(dǎo),第一象限內(nèi)生成直線(xiàn)的Bresenham算法思想如下:

(1)畫(huà)點(diǎn)(%i,yi)>dx=xj-xi,dy=yr-y\,計(jì)算誤差初值Pi=2dy-dx,i=l。

(2)求直線(xiàn)的下一點(diǎn)位置xi+i=Xi+1,如果Pj>0,則jr+i=yj+l>否則M+i=y”

(3)畫(huà)點(diǎn)(為+1,%+1)。

(4)求下一個(gè)誤差Pi+i,如果Pj>0,則Pl+l=P,+2dy-2dx,否貝UP,+1=P,+2dyo

(5)/=/+1;如果z<dx+l則轉(zhuǎn)步驟(2);否則結(jié)束操作。

圓的基本生成算法:

給出圓心坐標(biāo)(匕,%)和半徑r,逐點(diǎn)畫(huà)出一個(gè)圓周的方式有下列幾種。直角坐標(biāo)公式法直

角坐標(biāo)系的圓的方程為:

(X-+。-%了=/

由上式導(dǎo)出:

^22

y=%士r-(x-xc)

當(dāng)x-xc從-r至IJr做加1遞增時(shí),就可以求出對(duì)應(yīng)的圓周點(diǎn)的y坐標(biāo)。但是這樣求

出的圓周上的點(diǎn)是不均勻的,越大,對(duì)應(yīng)生成圓周點(diǎn)之間的圓周距離也就越長(zhǎng),如

圖圖4-4所示。因此,所生成的圓不美觀。

中點(diǎn)畫(huà)圓法

第32頁(yè)共32頁(yè)

如圖4-4所示,設(shè)函數(shù)為F(x,y)=x2+y2-R2,構(gòu)造圓,則點(diǎn)與圓的關(guān)系有以下3種情

況:

圓上的點(diǎn)F(x,y)=O;圓外的點(diǎn)F(x,y)>0;圓內(nèi)的點(diǎn)尸(x,y)<0;構(gòu)造判別式:

d=F(M)=F(Xp+1,坊-0.5)=%+1)2+(?-0.59

若d<0,則應(yīng)取Pi為下一像素,且下一-像素的判別式為

222

d=F(x/>+2,y/>-0.5)=(xp+2)+(y/,-0.5)-R=d+2x/,+3

若於0,則應(yīng)取P2為下一像素,且下一像素的判別式

討小論=按尸(x順「+時(shí)針2,力方-1.向5)生=(成第%+2)二2+(個(gè)y八廠(chǎng)1.5)分圓2-,“

則=d第一個(gè)+2(/-像素力)+5是

(0,R),判別式4的初始值為圖4-4中點(diǎn)畫(huà)圓法示意圖

4)=F(1,R-O.5)=1.25-R

圓的Bresenham算法》設(shè)圓的半徑為r,先考

慮圓心在(0,0),從x=0、

y=r開(kāi)始的順時(shí)針?lè)较虻?/8圓周的生成過(guò)程。在這>■

'種情況下,x每步增加1,從x=0開(kāi)始,到x=y結(jié)

束,,即有Xj+i=Xj+1;相應(yīng)的,yi+i則在兩種可能中

選擇:yZyi+i=yi或者yi+i=yi-1<>選擇的原則是考

察精確值y是靠近y還是靠近y「l(見(jiàn)圖4-5)。

計(jì)算公式為:

yi=n-(xi+\)2Ox<XMxd\-y,-2-y2=+(x,+1)2圖4-5確定y

2222

的位置d2=y-(y,-I)=r-(xj+l)-(y,-I)

令p尸4-42,并代入4、d2,則有

22

Pi=2(x;+1)+j,-+(y,-1尸-2/(4.6)

Pi稱(chēng)為誤差。如果pSO,則)■=?,否則y,-+i=yi-1?p,的遞歸

式為

第33頁(yè)共33頁(yè)

Pi+i=Pi+4x,+6+2(*+]_)/)_2G*LM)(4.7)

Pi的初值山式(4.6)代入x,=0,得

pi=3-2r(4.8)

根據(jù)上面的推導(dǎo),圓周生成算法思想如下:

(1)求誤差初值,pi=3-2r,i=l,畫(huà)點(diǎn)(0,r)。

(2)求下一個(gè)光柵位置,其中々+1F+1,如果p,<0則〉i+i=M,否則舟1=%-1。

(3)畫(huà)點(diǎn)(%+1,%+|)。

(4)計(jì)算下一個(gè)誤差,如果pi<0則Q+i=pi+4x,+6,否則pi+1=/>,+4(x,--y,)+10?i=i+1,

如果4y則結(jié)束,否則返回步驟(2)。

設(shè)計(jì)步驟:掌握原理——〉轉(zhuǎn)換成計(jì)算機(jī)語(yǔ)言—>編寫(xiě)編譯運(yùn)行程序

1)啟動(dòng)VC,選擇"Files件"|"New"菜單命令,并在彈出的新建對(duì)話(huà)框中單擊"工程"標(biāo)簽。

2)選擇MFCAppWizard(exe),在“Projectname”編輯框中輸入工程名稱(chēng),單擊“確定"按

鈕,出現(xiàn)應(yīng)用向?qū)Т翱跇?biāo)題MFCAppWizard—Step1of6對(duì)話(huà)框。

3)選擇"單文檔”選項(xiàng),單擊“NEXT"按鈕,出現(xiàn)Step2of6對(duì)話(huà)框。

4)接受默認(rèn)選項(xiàng),單擊"NEXT"按鈕,在出現(xiàn)的Step3?Step5對(duì)話(huà)框中,接受默認(rèn)選

項(xiàng),單擊"NEXT"按鈕。

5)在Step6對(duì)話(huà)框中單擊“完成"按鈕,即完成應(yīng)用程序的主要選項(xiàng),隨后出現(xiàn)工程信

息對(duì)話(huà)框(記錄以上步驟各選項(xiàng)的選擇情況),單擊"確定"按鈕,完成應(yīng)用程序框架的創(chuàng)建。

設(shè)計(jì)生成直線(xiàn)的DDA(數(shù)值微分)算法、中點(diǎn)畫(huà)線(xiàn)法、Bresenham算法的菜單項(xiàng)。在

工作空間ResourceView標(biāo)簽中,單擊Menu項(xiàng)左邊,然后雙擊其子項(xiàng)

IDR_MAINFRAME,

并根據(jù)表中定義的編輯菜單資源創(chuàng)建。

菜單標(biāo)題菜單項(xiàng)標(biāo)題標(biāo)不符ID

直線(xiàn)DDA算法生成直線(xiàn)ID_DDALINE

第34頁(yè)共34頁(yè)

Bresenham算法生成直線(xiàn)ID_BRESENHAMLINE

中點(diǎn)算法生成直線(xiàn)ID_MIDPOINTLINE

③添加消息處理函數(shù)

利用ClassWizard(類(lèi)向?qū)В閼?yīng)用程序添加與菜單項(xiàng)相關(guān)的消息處理函數(shù),Classname

欄中選擇CxxView,建立消息映射函數(shù),ClassWizard會(huì)自動(dòng)完成有關(guān)函數(shù)聲明。

菜單項(xiàng)ID消息消息處理函數(shù)

ID_DDALINECOMMANDOnDdaline

ID_MIDPOINTLINECOMMANDOnMidpointline

ID_BRESENHAMLINECOMMANDOnBresenhamline

在工作空間的Resourceview標(biāo)簽中,單擊Menu項(xiàng)左邊然后雙擊其子項(xiàng)

IDR_MAINFRAME,添加編輯菜單資源。建好的菜單有中點(diǎn)畫(huà)圓和Bresenham畫(huà)圓兩種方

法。

菜單標(biāo)題菜單項(xiàng)標(biāo)題標(biāo)示符ID

中點(diǎn)畫(huà)圓ID_MIDPOINTCIRCLE

Bresenham畫(huà)圓ID_BRESENHAMCIRCLE

(3)添加消息處理函數(shù)。

利用ClassWizard(建立類(lèi)向?qū)В閼?yīng)用程序添加與菜單項(xiàng)相關(guān)的消息處理函數(shù),

ClassName欄中選擇CxxView,建立如下的消息映射函數(shù),ClassWizard會(huì)自動(dòng)完成有關(guān)

的函數(shù)聲明。

菜單項(xiàng)ID消息消息處理函數(shù)

ID_MIDPOINTCIRCLECONMMANOnMidpointcircle

ID_BRESENHAMCIRCLECONMMANOnBresenhamcircle

//DDA算法生成直線(xiàn)

voidCGraphics_AIITestView::OnDdaline()

第35頁(yè)共35頁(yè)

〃TODO:Addyourcommandhandlercodehere

CDC*pDC=GetDC();〃獲得設(shè)備指針

intxa=100,ya=300,xb=300,yb=200,c=RGB(255,0,0);〃定義直線(xiàn)的兩端點(diǎn),直線(xiàn)顏色

intx,y;

floatxbyLdx,dy,k;

dx=(float)(xb-xa),dy=(float)(yb-ya);

k=dy/dx,y=ya;

if(abs(k)<l)

(

yi=ya;

for(x=xa;x<=xb;x++)

(

pDC->SetPixel(x,int(yl+0.5),c);

yl=yl+k;

)

)

if(abs(k)>=l)

{

xl=xa;

for(y=ya;y<=yb;y++)

(

pDC->SetPixel(int(xl+0.5),y,c);

xl=xl+1/k;

}

)

ReleaseDC(pDC);

)

第36頁(yè)共36頁(yè)

〃中點(diǎn)算法生成直線(xiàn)

voidCGraphics_AIITestView::OnMidpointline()

(

〃TODO:Addyourcommandhandlercodehere

CDC*pDC=GetDC();

intxa=300zya=200,xb=450,yb=300zc=RGB(0z255,0);

floata,b,dlzd2,d,x,y;

a=ya-yb,b=xb-xa,d=2*a+b;

dl=2*a,d2=2*(a+b);

x=xa,y=ya;

pDC->SetPixel(x/y,c);

while(x<xb)

(

if(d<0)

(

x++,y++,d+=d2;

}

else

(

x++,d+=dl;

)

pDC->SetPixel(x,y,c);

}

ReleaseDC(pDC);

)

第37頁(yè)共37頁(yè)

//Bresenham算法生成直線(xiàn)

voidCGraphics_AIITestView::OnBresenhamline()

(

〃TODO:Addyourcommandhandlercodehere

CDC*pDC=GetDC();

intxl=100,yl=200,x2=350zy2=100/c=RGB(0/0/255);

inti,si,s2,interchange;

floatx,y,deltax,deltayftemp;

x=xl;

y=yi;

deltax=abs(x2-xl);

deltay=abs(y2-yl);

if(x2-xl>=0)sl=l;elsesl=-l;

if(y2-yl>=0)s2=l;elses2=-l;

if(deltay>deltax)

(

temp=deltax;

deltax=deltay;

deltay=temp;

interchange=l;

)

else

(

interchanged;

f=2*deltay-deltax;

第38頁(yè)共38頁(yè)

pDC->SetPixel(xzy,c);

for(i=l;i<=deltax;i++)

if(f>=0)

if(interchange==l)

x+=sl;

else

y+=s2;

pDC->SetPixel(x,yzc);

f=f-2*deltax;

else

if(interchange==l)

y+=s2;

else

x+=sl;

第39頁(yè)共39頁(yè)

f=f+2*deltay;

)

)

〃中點(diǎn)算法繪制圓

voidCGraphics_AIITestView::OnMidpointcircle()

(

〃TODO:Addyourcommandhandlercodehere

CDC*pDC=GetDC();

intxc=300,yc=3OO,r=50zc=0;

intxzy;

floatd;

x=0;y=r;d=1.25-r;

pDC->SetPixel((xc+x),(yc+y),c);

pDC->SetPixel((xc?x),(yc+y),c);

pDC->SetPixel((xc+x),(yc-y),c);

pDC->SetPixel((xc-x),(yc-y),c);

pDC->SetPixel((xc+yj^yc+x^c);

pDC->SetPixel((xc-y),(yc+x)zc);

pDC->SetPixel((xc+yJXyc-x)^);

pDC->SetPixel((xc-y)z(yc-x)zc);

while(x<=y)

(

if(d<0)d+=2*x+3;

else{d+=2*(x-y)+5;y-;}

x++;

第40頁(yè)共40頁(yè)

pDC->SetPixel((xc+x),(yc+y)zc);

pDC->SetPixel((xc-xjjyc+y)^);

pDC->SetPixel((xc+x),(yc-y),c);

pDC->SetPixel((xc-x),(yc-y)zc);

pDC->SetPixel((xc+y),(yc+x),c);

pDC->SetPixel((xc-y),(yc+x),c);

pDC->SetPixel((xc+y)4yc-x)zc);

pDC->SetPixel((xc-y),(yc-x)zc);

}

)

//Bresenham算法繪制圓

voidCGraphics_AIITestView::OnBresenhamcircle()

(

//TODO:Addyourcommandhandlercodehere

CDC*pDC=GetDC();

intxc=100,yc=100,radius=50,c=0;

intx=0,y=radius/p=3-2*radius;

while(x<y)

(

pDC->SetPixel(xc+xzyc+y,c);

pDC->SetPixel(xc-x,yc+y,c);

pDC->SetPixel(xc+x,y

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論