版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
西南交通大學信息科學與技術(shù)學院
計算機圖形學實驗課
(2015?2016學年第H學期)
實
驗
報
告
學號:20132184姓名:朱彥榮
專業(yè):軟件工程班級:軟件工程2
第1頁共1頁
第2頁共2頁
課程名稱計算機圖形學
班級軟件工程2學號20132184姓名朱彥榮
實驗日期2016/3/23實驗成績
實驗名稱實驗一、鍵盤與鼠標按鍵消息處理實驗
1.實驗目的
熟悉集成開發(fā)環(huán)境和編輯操作,了解外圍設(shè)備的工作原理,根據(jù)設(shè)備特征和
產(chǎn)生的消息信號處理消息,管理設(shè)備。
2.實驗設(shè)備
設(shè)備編號設(shè)備名稱數(shù)量
1鼠標1
2鍵盤1
3主機1
4顯示器1
5網(wǎng)線1
第3頁共3頁
3.實驗設(shè)計過程說明
軟件設(shè)計工具名稱:__________VC++6.0____________________
實驗內(nèi)容:
①在鍵盤上進行按鍵操作,如果是可顯示字符,在屏幕上輸出對應的ASCII
碼;
②點擊鼠標左鍵,在屏幕上的客戶區(qū)窗口中鼠標點擊的位置,輸出一提示
字符串。
設(shè)計過程:
在VC++6.0中建立Win32Applicaption,然后在消息處理機制中添加相應的
處理事件,點擊運行即可;
基本工作原理:
該實驗的核心就是消息處理。消息,來自于事件(event),我們的所有操作無
外乎是對事件的處理。任何大的事件總能不斷細分成很多個基本事件,而基本事
件依據(jù)與硬件設(shè)備輸入設(shè)備的不同而增加。比如“點擊鼠標左鍵”這個事件就會
產(chǎn)生相應的消息,我們要做的就是對消息的處理了。根據(jù)上面的論證,我們可以
很輕松的理解這一環(huán)境編程的核心。當用戶在窗口上按下一個字符鍵,程序?qū)⒌?/p>
到一條WMJZHAR消息,在其wParam參數(shù)中含有字符的碼值,該消息包含了可
顯示字符的百值。當用戶按下鼠標左鍵,將產(chǎn)生WM_LBUTTONDOWN消息,可
以根據(jù)這些消息特征編寫消息處理函數(shù),并在窗口中輸出對應的文字信息,管理
設(shè)備。
設(shè)計步驟:
建立工程->編寫消息處理函數(shù)-〉運行程序,觀察結(jié)果
第4頁共4頁
#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為零,則說明正運行的這個實例是程序的第一個實例,
〃僅當運行第一個實例時;需要注冊窗口類(對16位程序而言)
〃注冊窗口類如下:
wcGRF.IpszClassName=szTitle;〃窗口類的類名
第5頁共5頁
wcGRF.hlnstance=hlnstance;〃定義該類的應用程序的句柄
wcGRF.IpfnWndProc=WndProc;〃窗口函數(shù)
wcGRF.hCursor=LoadCursor(NULL,IDCCROSS);//光標對象的句柄
wcGRF.hlcon=LoadIcon(NULL,IDIAPPLICATION);〃圖標對象的句柄
wcGRE.IpszMenuName=NULL;〃標識菜單對象的字符串
wcGRF.hbrBackground=(HBRUSH)::GetStockObject(WHITE_BRUSH);
//usedtoclearhandle
wcGRF.style=CS_HREDRAW|CS_VREDRAW;//windowsstyle;
wcGRF.cbClsExtra=0;〃類變量占據(jù)的存儲空間
wcGRF.cbWndExtra=0;〃實例變量占用的存儲空間
if(!RegisterClass(&wcGRF))//如注冊失敗則返回
returnFALSE;
)
//對每個實例創(chuàng)建一個窗口對象
hWnd=CreateWindow(szTitle,〃類名,指定該窗口所屬的類
szTitle,〃窗口名,即在標題欄顯示的文本
WSOVERLAPPEDWINDOW,
//窗口風格,以下四個參數(shù)確定窗口初始位置及大小
30,〃窗口左上角相對屏幕的X坐標
30,〃窗口左上角相對屏幕的Y坐標
540,〃窗口寬度
360,〃窗口高度
第6頁共6頁
NULL,〃父窗口句柄
NULL,〃菜單句柄
hlnstance,〃實例句柄
NULL);〃額外參數(shù)
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
〃消息循環(huán)
while(GetMessage(&msg,NULL,0,0))〃從應用程序隊列中取出?條消息
(
TranslateMessage(&msg);〃翻譯消息
DispatchMessage(&msg);〃發(fā)送消息
)
return(msg.wParam);
}
LRESULTCALLBACKWndProc(HWNDhWnd,UINTMsg,WPARAMwParam,LPARAMIParam)
{
HDChDC;
switch(Msg)
!
caseWM_CHAR:
charstr[40];
第7頁共7頁
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里必須用這個函數(shù)
TextOut(hDC,0,0,〃MouseLeftButtonandKeyTest”,strlen(z,MouseLeft
ButtonandKeyTest"));
EndPaint(hWnd,&ps);
break;
caseWMDESTROY:
第8頁共8頁
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頁共9頁
return0;
caseWM_DESTR0Y:
PostQuitMessage(0);
return(0);
)
returnDefWindowProc(hWnd,messg,wParam,1Param);
}*/
執(zhí)行順序:
消息的分派和處理
實驗結(jié)果記錄:
單擊鼠標左鍵:
點擊確定后:
clickmouseleft
第10頁共10頁
在鍵盤上點擊a得到的結(jié)果:
4.實驗結(jié)果的分析和描述
由實驗的內(nèi)容和環(huán)境可以知道,該實驗的核心就是消息處理。說起消息處理,
這是模仿人類社會工作方式的一種仿真模式。消息,來自于事件(event),我們
的所有操作無外乎是對事件的處理。任何大的事件總能不斷細分成很多個基本事
件,而基本事件依據(jù)與硬件設(shè)備輸入設(shè)備的不同而增加。比如“點擊鼠標左鍵”
這個事件就會產(chǎn)生相應的消息,我們要做的就是對消息的處理了。根據(jù)上面的論
證,我們可以很輕松的理解這一環(huán)境編程的核心。
核心代碼分析:
這個實驗主要是兩個輸入設(shè)備上的測試,首先是鍵盤,當我們按下鍵盤上的一
個鍵時,會經(jīng)過很復雜的過程,比如8042、8048等硬件最終將按下鍵的make,
break碼等傳入緩沖區(qū)中,并且在此程序中會產(chǎn)生WM_CHAR這一消息,我們要
做的就是對這個消息的處理了,很簡單的,操作系統(tǒng)已經(jīng)為我們屏蔽了很多的細
節(jié)。同樣,點擊鼠標也是同樣的道理,不再一一贅述了。
實驗結(jié)果的分類:點擊鼠標,彈出對話框;按下按鍵,彈出對話框。
各個主要組成部分的說明:主要是消息處理的代碼。
存在的問題:功能簡陋
可以改進的方面和建議:可以添加更加復雜的消息處理事件,使得整個程序更加
系統(tǒng)化。
第11頁共11頁
第12頁共12頁
課程名稱計算機圖形學
班級:軟件工程2學號:20132184姓名:朱彥榮
實驗日期:2016/3/30實驗成績:
實驗名稱:實驗二、窗口移植與簡單圖案繪制實驗
1.實驗目的
掌握計算機圖形學編程實現(xiàn)最基本的圖形程序的步驟和方法.
2.實驗設(shè)備
設(shè)備編號設(shè)備名稱數(shù)量
1鼠標1
2鍵盤1
3主機1
4顯示器1
5網(wǎng)線1
第13頁共13頁
3.實驗設(shè)計過程說明
軟件設(shè)計工具名稱:_________VC++6.0___________________
實驗內(nèi)容:窗口移植與簡單圖案繪制
設(shè)計過程:編寫程序->編譯運行->逐步迭代改進->得出結(jié)果
基本工作原理:
這次的實驗目的是讓我們更好的理解框架和使用繪圖函數(shù),因此繪圖的原理
很簡單。
設(shè)計步驟:編寫程序->編譯運行->逐步迭代改進->得出結(jié)果
voidCPaint_simp1e_graphicsView::OnDraw(CDC*pDC)
(
CPaint_simp1e_graphicsDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
//TODO:adddrawcodefornativedatahere
〃建立畫筆
CPenpen_Zuobixi;
第14頁共14頁
pen_Zuobixi.CreatePen(PS_SOLID,4,RGB(0,0,0));
pDC->SelectObject(&pen_Zuobixi);
〃指定原點
pDC->SetViewportOrg(100,255);
pDC->SetTextColor(RGB(255,0,0));
〃繪制橫坐標
CStringsPIText□={〃一1/2兀〃/〃,〃:1/2?!?,〃?!?,〃3/2”〃,〃2兀〃,〃5/2兀
〃,〃3?!ǎ?/2?!?,〃4兀〃,〃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;
〃繪制縱坐標
for(n=-4,nTemp=0;nTemp<=180;n++,nTemp+=60)
第15頁共15頁
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坐標/曲線寬度*角系數(shù)*n
//Y坐標二振幅*曲線寬度*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í)行順序:當程序運行的時候會自動調(diào)用OnDraw()的內(nèi)容,程序就自動執(zhí)行了。
實驗結(jié)果記錄:
第16頁共16頁
4.實驗結(jié)果的分析和描述
窗口移植,是窗口繪制代碼的一種移植。在MFC平臺下,我們可以自己搭建
相應的窗口顯示環(huán)境,具體的方法比較固定。簡單圖案的繪制,主要是考差了我
們繪制基本的圖案的能力,其中涉及了圖案的布局、計算、顯示等操作。在這里
我畫了一個正弦函數(shù)。
實驗結(jié)果的分類:繪圖類、窗口移植類
各個主要組成部分的說明:繪圖的步驟,與當前窗口的關(guān)聯(lián)。
存在的問題:程序還是過于簡單。
可以改進的方面和建議:可以增加更多的繪圖元素,豐富視覺感受。
第17頁共17頁
第18頁共18頁
課程名稱計算機圖形學
班級軟件工程2學號20132184姓名朱彥榮
實驗日期2016/4/6實驗成績
實驗名稱實驗三、指針式橢圓形實時顯示時鐘設(shè)計實驗
1.實驗目的
掌握定時器的響應處理方式,掌握簡單繪圖函數(shù)的使用和應用程序設(shè)計。
2.實驗設(shè)備
設(shè)備編號設(shè)備名稱數(shù)量
1鼠標1
2鍵盤1
3主機1
4顯示器1
5網(wǎng)線1
第19頁共19頁
3.實驗設(shè)計過程說明
軟件設(shè)計工具名稱:___________VC++6.0___________________
實驗內(nèi)容:利用消息映射與類中對應的成員函數(shù),設(shè)計一個指針式橢圓形實
時顯示時鐘。
設(shè)計過程:分析題目制定解決方案——>編寫時鐘程序——>得出結(jié)論。
基本工作原理:每隔一段時間,定時器就會自動調(diào)用重繪函數(shù)刷新屏幕,最終
畫出當前時間對應的時鐘。
設(shè)計步驟:分析題目制定解決方案——>編寫時鐘程序——>得出結(jié)論。
單擊VIEW菜單的ClassWizard項,在顯示的MFCClassWizard對話框中的Class
name選項中,選擇CTestView類;在Messages選項中,選中WM_TIMER消息,如圖所示,
目前WMTIMER消息還沒有相對應的類的成員函數(shù)。
第20頁共20頁
選中WM_TIMER消息單擊ADDFUNCTION按鈕,就會在該類中添加與該消息對應的成員
函數(shù)。本例中,為W_TIMER消息在類中添加了對應的成員函數(shù)OnTimer,如圖所示。
添加類中與消息對應的成員函數(shù)單擊EditCode按鈕,可以看到系統(tǒng)已經(jīng)自動生成了處理
WMJIMER消息所對應的函數(shù)OnTimer所需的基本代碼。
對于每個成員函數(shù),在需要修改的函數(shù)中找到的注釋語句“〃TODO”之下,再添加所
第21頁共21頁
需要的應用代碼就可以達到各自應用的目標了,函數(shù)OnTimer修改后的相應代碼如下:
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
〃獲取客戶區(qū)
RECTRect;
GetClientRect(&Rect);
〃計算橢圓中心位置
intCenterX=Rect.right/2;
intCenterY=Rect.bottom/2;
〃取當前時間
CTimeTime=CTime::GetCurrentTime();
CStringstr;
inti,x,y;
CSizesize;
第22頁共22頁
CPenPen2(PS_SOIJD,10,RGB(123,60,64));
〃先記下以前的畫筆,再設(shè)置當前畫筆
CPen*01dPen2=pDC->Select0bject(&Pen2);
pDC->Ellipse(5,5,Rect.right-5,Rect.bottom-5);
〃創(chuàng)建一支黑色的筆,用來畫橢圓
CPenPen(PS_S0LID,20,RGB(3,234,64));
〃先記下以前的畫筆,再設(shè)置當前畫筆
CPen*01dPen=pDC->SelectObject(&Pen);
//繪制鐘面橢圓
pDC->Ellipse(20,20,Rect.right_20,Rect.bottom-20);
CPenPenl(PS_S0LID,3,RGB(3,3,64));
〃先記下以前的畫筆,再設(shè)置當前畫筆
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++){
〃格式化鐘點值
str.Format("%d”,i);
size=pDC->GetTextExtent(str,str.GetLengthO);
Radians=(double)i*6.28/12.0;
〃計算鐘點放置的位置
x=CenterX-(size,cx/2)+(int)((double)(CenterX-20)*
第23頁共23頁
sin(Radians));
y=CenterY-(size.cy/2)-(int)((double)(CenterY-20)*
cos(Radians));
〃繪制鐘點
pDC->TextOut(x,y,str);
)
〃計算時鐘指針的夾角
Radians=(double)Time.GetHour()+(double)Time.GetMinute()/60.0+
(double)Time.GetSecond()/3600.0;
Radians*=6.28/12.0;
〃創(chuàng)建時鐘指針畫筆
CPenHourPen(PS_S0LID,5,RGB(255,255,0));
pDC->SelectObject(&HourPen);
〃繪制時鐘指針
pDC->MoveTo(CenterX,CenterY);
pDC->LineTo(CenterX+(int)((double)(CenterX/3)*sin(Radians)),
CenterY-(int)((double)(CenterY/3)*cos(Radians)));
〃計算分鐘指針的夾角
Radians=(double)Time.GetMinute()+(double)Time.GetSecond()/60.0;
Radians*=6.28/60.0;
〃創(chuàng)建分鐘指針畫筆
CPenMinutePen(PS_S0LID,3,RGB(255,0,255));
pDC->SelectObject(&MinutePen);
〃繪制分鐘指針
第24頁共24頁
pDC->MoveTo(CenterX,CenterY);
pDC->LineTo(CenterX+(int)((double)(CenterX*2)/3)*sin(Radians),
CenterY-(int)((double)(CenterY*2/3)*cos(Radians)));
〃計算秒鐘指針的夾角
Radians=(double)Time.GetSecondO;
Radians*=6.28/60.0;
〃創(chuàng)建秒鐘指針畫筆
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順序:編譯運行后,定時器采用中斷方式不斷地刷新屏幕。
實驗結(jié)果記錄:
第25頁共25頁
4.實驗結(jié)果的分析和描述
設(shè)當前需要顯示的時間為Hour時Minute分Second秒,則經(jīng)過簡單計算就可
得到各個指針實時顯示夾角。計算依據(jù)為:
時鐘指針實時顯示的夾角:AHour=(Hour+Minute左0+Second/3600)*2n/12;
分鐘指針實時顯示的夾角:AMinute=(Minute+Second^O)*2”由0;
秒鐘指針實時顯示的夾角:ASecond=Second*2n/60;
時鐘的鐘面用橢圓形顯示,橢圓的中心位置可以確定在客戶窗口的顯示中心;繪
制時、分、針時,用不同顏色的直線段顯示,長度分別為橢圓半長軸的3、羽、
奶;時鐘表面的時間刻度,可用角度劃分的方式均勻劃分成12份,并用1~12
的數(shù)字表示。時間的獲取方法:利用計時器的響應函數(shù)處理,每秒鐘更新一次時
鐘畫面,重畫時鐘的各個指針,各指針的位置可以通過顯示夾角的計算得到,達
到實時顯示時鐘的目標。
實驗結(jié)果的分類:時鐘繪制類、時間刷新類。
各個主要組成部分的說明:注意定時器的運用o
第26頁共26頁
存在的問題:可以讓始終更加美觀?點。
可以改進的方面和建議:增加更多的設(shè)計理念美化時鐘。
第27頁共27頁
第28頁共28頁
課程名稱計算機圖形學
班級軟件工程2學號20132184姓名朱彥榮
實驗日期2016/4/13實驗成績
實驗名稱實驗四、計算機圖形學直線與圓的基本繪圖算法實驗
1.實驗目的
本節(jié)主要講述如何在指定的輸出設(shè)備(如光柵圖形顯示器)上利用點構(gòu)造其他
基本二維幾何圖形(如點、直線、圓、橢圓、多邊形域及字符串等)的算法與
原理,并利用VisualC++編程實現(xiàn)這些算法。
2.實驗設(shè)備
設(shè)備編號設(shè)備名稱數(shù)量
1鼠標1
2鍵盤1
3主機1
4顯示器1
5網(wǎng)線1
第29頁共29頁
3.實驗設(shè)計過程說明
軟件設(shè)計工具名稱:____________VC++6.0____________________
實驗內(nèi)容:直線與圓的基本繪圖算法___________________
設(shè)計過程:掌握原理——>轉(zhuǎn)換成計算機語言——>編寫編譯運行程序
基本工作原理:
畫直線算法:
(1)DDA(數(shù)值微分)算法
DDA算法原理:如圖4-1所示,已知過端點出(項,%),。1?,)])的直線段PMi;
直線斜率為k=(yLyo)/(Xi-xo),從x的左端點X。開
始,向x右端點步進畫線,步長=1(個像素),計算
相應的y坐標y=kx+B;取像素點[x,round(y)]
作為當前點的坐標。
計算》+|=kxj+i+B=kx\+B+k&c=y\+kL
x,當Ax=1,M+I=),,?+k,即當x每遞增1,y遞增k(即直線斜率)。
注意分析:上述算法僅適用于^<1的情形。在這
第30頁共30頁
種情況下,X每增加l,y最多增加lo當Z21時,必圖4-1直線DDA算法掃描轉(zhuǎn)換
須把x,y地位互換,y每增加1,x相應增加11k。
(2)直線的中點畫線法中點畫線法的基本原理如圖4-2所示。在畫直線段的過程中,
當前像素點為P,下一個像素點有兩種選擇,點Pi或2。
M為Pi與P2中點,Q為理想直線與X=X,+1垂線的交
點。當M在。的下方時,則上方的P2應為下一個像素
點;當M在Q的上方時,應取下方的Pi為下一點。
中點畫線法的實現(xiàn):
令直線段為L[po(Xo,yo),pGiji)],其方程式F(x,y)=ax+by+c=Q?
其中,-i,6=兩-沏,。=91一由加
點與L的關(guān)系如下:P=(xp,yp)在直線上,F(xiàn)(x,y)=0;
中點畫線法每步迭代
在直線上方,F(xiàn){x,y)>0;
在直線下方,F(xiàn)(x,y)<0。涉及的像素和中點示意圖把M代入尸(x,y),判斷F
的符號,可知Q點在中點M的上方還是下方。為此構(gòu)造判別式d=F(M)=F(Xp+l,
為+0.5)=〃(而+1)+6(切+0.5)+c。當4<0,UQ點)在M上方,取P2為下一個像
素。當d>0,L(Q點)在M下方,取Pi為下一個像素。當d=0,選4或尸2
均可,取P,為下一個像素。其中d是xp,y?的線性函數(shù)。
=mx+b,其中b-y\-mx\,m=(?-乃)/(工廠4)=dy/dx;此處的
討論直線方向限于第像限,如圖4-3所示,當直線光柵化時,x每次都增加1個單
元,設(shè)x像素為(如%)。下一個像素的列坐標為8+1,行坐標為y或者遞增1為》+1,
由y與4-3第一象限直線光柵化
第31頁共31頁
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-總大于0,所以P,仍然可以用做判斷誤差的符號。PM為
Pi+1=P,-+2dy-2(yi+i-y,)dr(4.5)
求誤差的初值Pi,可將為、M和b代入式(4.4)中的毛、%,而得到
Pi=2dy-dx
綜合上面的推導,第一象限內(nèi)生成直線的Bresenham算法思想如下:
(1)畫點(%i,yi)>dx=xj-xi,dy=yr-y\,計算誤差初值Pi=2dy-dx,i=l。
(2)求直線的下一點位置xi+i=Xi+1,如果Pj>0,則jr+i=yj+l>否則M+i=y”
(3)畫點(為+1,%+1)。
(4)求下一個誤差Pi+i,如果Pj>0,則Pl+l=P,+2dy-2dx,否貝UP,+1=P,+2dyo
(5)/=/+1;如果z<dx+l則轉(zhuǎn)步驟(2);否則結(jié)束操作。
圓的基本生成算法:
給出圓心坐標(匕,%)和半徑r,逐點畫出一個圓周的方式有下列幾種。直角坐標公式法直
角坐標系的圓的方程為:
(X-+。-%了=/
由上式導出:
^22
y=%士r-(x-xc)
當x-xc從-r至IJr做加1遞增時,就可以求出對應的圓周點的y坐標。但是這樣求
出的圓周上的點是不均勻的,越大,對應生成圓周點之間的圓周距離也就越長,如
圖圖4-4所示。因此,所生成的圓不美觀。
中點畫圓法
第32頁共32頁
如圖4-4所示,設(shè)函數(shù)為F(x,y)=x2+y2-R2,構(gòu)造圓,則點與圓的關(guān)系有以下3種情
況:
圓上的點F(x,y)=O;圓外的點F(x,y)>0;圓內(nèi)的點尸(x,y)<0;構(gòu)造判別式:
d=F(M)=F(Xp+1,坊-0.5)=%+1)2+(?-0.59
若d<0,則應取Pi為下一像素,且下一-像素的判別式為
222
d=F(x/>+2,y/>-0.5)=(xp+2)+(y/,-0.5)-R=d+2x/,+3
若於0,則應取P2為下一像素,且下一像素的判別式
為
討小論=按尸(x順「+時針2,力方-1.向5)生=(成第%+2)二2+(個y八廠1.5)分圓2-,“
則=d第一個+2(/-像素力)+5是
(0,R),判別式4的初始值為圖4-4中點畫圓法示意圖
4)=F(1,R-O.5)=1.25-R
圓的Bresenham算法》設(shè)圓的半徑為r,先考
慮圓心在(0,0),從x=0、
y=r開始的順時針方向的1/8圓周的生成過程。在這>■
'種情況下,x每步增加1,從x=0開始,到x=y結(jié)
束,,即有Xj+i=Xj+1;相應的,yi+i則在兩種可能中
選擇:yZyi+i=yi或者yi+i=yi-1<>選擇的原則是考
察精確值y是靠近y還是靠近y「l(見圖4-5)。
計算公式為:
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稱為誤差。如果pSO,則)■=?,否則y,-+i=yi-1?p,的遞歸
式為
第33頁共33頁
Pi+i=Pi+4x,+6+2(*+]_)/)_2G*LM)(4.7)
Pi的初值山式(4.6)代入x,=0,得
pi=3-2r(4.8)
根據(jù)上面的推導,圓周生成算法思想如下:
(1)求誤差初值,pi=3-2r,i=l,畫點(0,r)。
(2)求下一個光柵位置,其中々+1F+1,如果p,<0則〉i+i=M,否則舟1=%-1。
(3)畫點(%+1,%+|)。
(4)計算下一個誤差,如果pi<0則Q+i=pi+4x,+6,否則pi+1=/>,+4(x,--y,)+10?i=i+1,
如果4y則結(jié)束,否則返回步驟(2)。
設(shè)計步驟:掌握原理——〉轉(zhuǎn)換成計算機語言—>編寫編譯運行程序
1)啟動VC,選擇"Files件"|"New"菜單命令,并在彈出的新建對話框中單擊"工程"標簽。
2)選擇MFCAppWizard(exe),在“Projectname”編輯框中輸入工程名稱,單擊“確定"按
鈕,出現(xiàn)應用向?qū)Т翱跇祟}MFCAppWizard—Step1of6對話框。
3)選擇"單文檔”選項,單擊“NEXT"按鈕,出現(xiàn)Step2of6對話框。
4)接受默認選項,單擊"NEXT"按鈕,在出現(xiàn)的Step3?Step5對話框中,接受默認選
項,單擊"NEXT"按鈕。
5)在Step6對話框中單擊“完成"按鈕,即完成應用程序的主要選項,隨后出現(xiàn)工程信
息對話框(記錄以上步驟各選項的選擇情況),單擊"確定"按鈕,完成應用程序框架的創(chuàng)建。
設(shè)計生成直線的DDA(數(shù)值微分)算法、中點畫線法、Bresenham算法的菜單項。在
工作空間ResourceView標簽中,單擊Menu項左邊,然后雙擊其子項
IDR_MAINFRAME,
并根據(jù)表中定義的編輯菜單資源創(chuàng)建。
菜單標題菜單項標題標不符ID
直線DDA算法生成直線ID_DDALINE
第34頁共34頁
Bresenham算法生成直線ID_BRESENHAMLINE
中點算法生成直線ID_MIDPOINTLINE
③添加消息處理函數(shù)
利用ClassWizard(類向?qū)В閼贸绦蛱砑优c菜單項相關(guān)的消息處理函數(shù),Classname
欄中選擇CxxView,建立消息映射函數(shù),ClassWizard會自動完成有關(guān)函數(shù)聲明。
菜單項ID消息消息處理函數(shù)
ID_DDALINECOMMANDOnDdaline
ID_MIDPOINTLINECOMMANDOnMidpointline
ID_BRESENHAMLINECOMMANDOnBresenhamline
在工作空間的Resourceview標簽中,單擊Menu項左邊然后雙擊其子項
IDR_MAINFRAME,添加編輯菜單資源。建好的菜單有中點畫圓和Bresenham畫圓兩種方
法。
菜單標題菜單項標題標示符ID
中點畫圓ID_MIDPOINTCIRCLE
圓
Bresenham畫圓ID_BRESENHAMCIRCLE
(3)添加消息處理函數(shù)。
利用ClassWizard(建立類向?qū)В閼贸绦蛱砑优c菜單項相關(guān)的消息處理函數(shù),
ClassName欄中選擇CxxView,建立如下的消息映射函數(shù),ClassWizard會自動完成有關(guān)
的函數(shù)聲明。
菜單項ID消息消息處理函數(shù)
ID_MIDPOINTCIRCLECONMMANOnMidpointcircle
ID_BRESENHAMCIRCLECONMMANOnBresenhamcircle
//DDA算法生成直線
voidCGraphics_AIITestView::OnDdaline()
第35頁共35頁
〃TODO:Addyourcommandhandlercodehere
CDC*pDC=GetDC();〃獲得設(shè)備指針
intxa=100,ya=300,xb=300,yb=200,c=RGB(255,0,0);〃定義直線的兩端點,直線顏色
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頁共36頁
〃中點算法生成直線
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頁共37頁
//Bresenham算法生成直線
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頁共38頁
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頁共39頁
f=f+2*deltay;
)
)
〃中點算法繪制圓
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頁共40頁
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. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 種植業(yè)基礎(chǔ)試題及答案解析
- 家具公司噪音控制實施方案
- 整形市場人員培訓
- 機制地毯擋車工操作技能考核試卷含答案
- 飛機供氧系統(tǒng)調(diào)試工崗前安全教育考核試卷含答案
- 2025-2030中國智能音箱市場用戶習慣變遷與商業(yè)模式創(chuàng)新報告
- 油墨制造工安全實操考核試卷含答案
- 環(huán)氧乙烷(乙二醇)裝置操作工安全素養(yǎng)水平考核試卷含答案
- 土方機械維修工崗前認證考核試卷含答案
- 磚瓦干燥工安全強化測試考核試卷含答案
- 村莊規(guī)劃搬遷方案
- 安全文明施工措施方案
- 鋼結(jié)構(gòu)課程設(shè)計-車間工作平臺
- 融資租賃實際利率計算表
- 民爆物品倉庫安全操作規(guī)程
- von frey絲K值表完整版
- 勾股定理復習導學案
- 第二章單自由度系統(tǒng)振動
- GB/T 17880.6-1999鉚螺母技術(shù)條件
- SB/T 11094-2014中藥材倉儲管理規(guī)范
- GB/T 6418-2008銅基釬料
評論
0/150
提交評論