




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、華中科技大學電子科學與技術系課程設計報告( 2010- 2011年度第 2 學期)名 稱: 軟件課程設計 題 目: 基于OpenGL的3D旋轉(zhuǎn)魔方實現(xiàn) 院 系: 班 級: 學 號: 學生姓名: 指導教師: 設計周數(shù): 成 績: 日期: 年 月 日目 錄. 2. 2. 22. 32.1 程序原理32.2 程序流程42.3 數(shù)據(jù)結(jié)構132.4 重要函數(shù)1316 3.1 成果演示16 3.2 程序分析171819 21世紀是高科技時代,是信息技術時代,而計算機技術無疑會引領各行各業(yè),為我們帶來一個全新的時代。作為新世紀的接班人,我們必須擁有良好的計算機應用能力,才能跟上世界發(fā)展的大流,不至于在激烈的
2、競爭中被淘汰。而程序作為計算機的靈魂,因此編程能力對當代大學生來說至關重要。通過本課程單元的學習,可以對軟件工程項目從整體上有一個較清晰的了解和認識;可以提高自身軟件編程能力,培養(yǎng)對計算機編程興趣,培養(yǎng)良好的編程習慣。同時編程時的態(tài)度和方法對我們今后的學習和工作也有重要影響。所以整體看來軟件課程設計這門課程提高了我們計算機使用水平,培養(yǎng)了我們良好的學習態(tài)度,對我們個人的發(fā)展而言有著重要的意義。 1.2 內(nèi)容 (1)鞏固和加強c語言相關編程知識,學會用Visual C+6.0進行c語言編程。(2)掌握程序設計流程和思想,模塊化結(jié)構分析以及程序設計流程,初步培養(yǎng)需求分析、軟件測試、調(diào)試的能力。 (
3、3)掌握win32相關編程知識,了解windows程序內(nèi)部運行機制。 (4)掌握OpenGL貼圖技術原理與函數(shù)實現(xiàn),掌握OpenGL幾何的移動、旋轉(zhuǎn)等模式變化的原理。 (5)掌握魔方圖形構造原理,在掌握二階魔方構造原理的基礎上,構造出三階魔方并實現(xiàn)其旋轉(zhuǎn)。 1.3 取得的成果 在理解和掌握老師所給的范例程序的基礎上,借助Win32平臺進行了一系列調(diào)試和學習,熟練掌握了Win32 Application開發(fā)流程。同時也學習和了解了OpenGL的基本知識,掌握了一些OpenGL的重要技術與重要函數(shù)的使用,編寫了一些簡單的OpenGL程序。在比較透徹的了解了二階魔方的構造原理后,成功地構造出了三階魔
4、方,換上了自己班級同學的圖片,并且在一個小立方體的六個面上貼上了不同的圖片。能夠比較完美的實現(xiàn)三階魔方各個層面的隨機旋轉(zhuǎn),并且把窗口背景設置為紅色。為了使程序更加有趣,我在程序中導入了劉德華的愛你一萬年這首歌,使魔方在旋轉(zhuǎn)的同時能夠播放歌曲。除此之外,我還實現(xiàn)了一種三階魔方自由移動的屏保效果:即三階魔方在旋轉(zhuǎn)的同時能夠在屏幕內(nèi)部自由移動,并且在邊緣無限次的反彈。在魔方平移的過程中同樣可以通過四個方向鍵來控制魔方的移動。當松開方向鍵后,魔方會繼續(xù)按照先前的方式自由移動。2.1 程序原理(1)OpenGLOpenGL是為Open Graphics Library的簡稱,它是3D繪圖工業(yè)標準,廣泛地
5、應用于計算機3D繪圖領域。它是個專業(yè)的開放的3D程序接口,是一個功能強大,調(diào)用方便的底層3D圖形庫。它獨立于窗口系統(tǒng)和操作系統(tǒng),以它為基礎開發(fā)的應用程序可以十分方便地在各種平臺間移植;OpenGL可以與Visual C+緊密接口,便于實現(xiàn)機械手的有關計算和圖形算法,可保證算法的正確性和可靠性;它具有七大功能:建模、變換、顏色模式設置、光照和材質(zhì)設置、紋理映射、位圖顯示和圖象增強和雙緩存動畫功能。OpenGL使用簡便,效率高。 本項目是在開發(fā)環(huán)境下,使用OpenGL函數(shù)庫,繪制魔方并實現(xiàn)魔方貼圖、隨機旋轉(zhuǎn)、以及鍵盤控制等功能。采用基本圖形的繪圖函數(shù)及定位函數(shù),添加相應紋理來實現(xiàn)魔方模型的繪制。通
6、過讀取載入BMP文件,應用紋理貼圖技術來完成對魔方旋轉(zhuǎn)面的處理。通過OpenGL中對圖形的旋轉(zhuǎn)和平移函數(shù)來實現(xiàn)對魔方整體的旋轉(zhuǎn)和平移。 (2)旋轉(zhuǎn) 在建立好空間三維模型后,要實現(xiàn)魔方體每一層面的旋轉(zhuǎn)。而魔方體每一層面的旋轉(zhuǎn)歸結(jié)于每一個小立方體的旋轉(zhuǎn)。每個小立方體的旋轉(zhuǎn)又最終歸結(jié)于每個點的旋轉(zhuǎn)。對于一個坐標為(x,y,z)的點,如果圍繞z軸逆時針旋轉(zhuǎn)角度為a,則旋轉(zhuǎn)之后z坐標不變,x和y坐標分別變?yōu)閤*cosa - y*sina,x*sina + y*cosa,如圖1所示: 圖1 這樣,實現(xiàn)了每個點的旋轉(zhuǎn),針對每個立方體只需采用循環(huán)對8個點均采取旋轉(zhuǎn)操作就可實現(xiàn)一個立方體的旋轉(zhuǎn)。 (3)消息循環(huán)
7、與定時器 由于程序在運行時CPU只能執(zhí)行一個任務,然而此項目中魔方在旋轉(zhuǎn)的同時要實現(xiàn)平移,所以需要用到Win32中的定時器功能。此程序中要用到的定時器的函數(shù)原型為:SetTimer(HWND hWnd ,UINT nIDEvent,UINT uElapse,TIMERPROC lpTimerFunc) HWND hWnd為窗口句柄,使程序和定時器建立聯(lián)系,UINT nIDEvent是 定時器ID,用于區(qū)分不同的定時器;UINT uElapse為定時器觸發(fā)周期,意味著多長時間執(zhí)行一次;,TIMERPROC lpTimerFunc為該定時器執(zhí)行時觸發(fā)的函數(shù)。所以控制好不同定時器的觸發(fā)周期
8、和觸發(fā)函數(shù),就能使魔方的各個層面的旋轉(zhuǎn)和平移互不沖突。 2.2 程序流程(1)WinMain主函數(shù) WinMain主函數(shù)是所有Win32程序的入口點。在WinMain函數(shù)里窗體的建立和消息循環(huán),在消息循環(huán)中實現(xiàn)鍵盤、鼠標輸入事件處理響應。在本程序中,要創(chuàng)建Window窗體和構建OpenGL設備繪圖環(huán)境。Window窗體創(chuàng)建步驟:l 窗體類注冊:RegisterClassl 設置顯示分辨率:ChangeDisplaySettingsl 設置窗體大?。篈djustWindowRectExl 創(chuàng)建窗體:CreateWindowExOpenGL繪圖環(huán)境搭建:l 獲取設備繪圖環(huán)境(DC,DeviceCo
9、ntext):hDC=GetDC(hWnd)l 選擇繪圖環(huán)境像素格式:ChoosePixelFormat(hDC,&pfd),其中pfd為像素格式描述符,如果設置不對,OpenGL繪圖失敗,看不到正確的顯示結(jié)果。l 設置繪圖環(huán)境像素格式:SetPixelFormat(hDC,PixelFormat,&pfd)l 獲取OpenGL繪圖環(huán)境:hRC =wglCreateContext(hDC)l 設置OpenGL繪圖環(huán)境:wglMakeCurrent(hDC,hRC)(2)三維建模一個三階魔方體由27個小立方體構成,每個小立方體由8個頂點組成,而每個頂點又有x,y,z三個方向上的坐
10、標值。這樣由結(jié)構體的層層嵌套就可以對魔方體的每個小立方體、每個頂點進行操作。typedef struct GLfloat p3; /定義一個點的x,y,z坐標值stPoint;typedef struct stPoint CubePoint8;/定義一個小立方體的8個頂點stCube;如圖2: 圖2 stCube Cube27; /定義魔方體的27個小立方體其中一個難點是怎樣根據(jù)各個點的坐標值構造出魔方體,其實只要定義好每個頂點的坐標就行了。但是三階魔方必須定義27*8=216個頂點的坐標值,而且很難用for循環(huán)實現(xiàn),因為各個頂點的x,y,z坐標值幾乎沒有什么規(guī)律。但是如果能夠?qū)⒁粋€小魔方體作
11、為一個整體來看待,工作量似乎會減輕很多。先在整個魔方體中間定義一個基準小立方體,則整個魔方體的各個小立方體均可以通過這個基準立方體的平移來實現(xiàn),各個小立方體上各點的平移向量和小立方體中心的平移向量相同。static stPoint CubePoint8= /定義好基準小立方體,邊長為1 -0.5f, -0.5f, 0.5f, /0 - 0.5f, -0.5f, 0.5f , /1 0.5f, 0.5f, 0.5f , /2 -0.5f, 0.5f, 0.5f, /3-0.5f, -0.5f, -0.5f,/4 -0.5f, 0.5f, -0.5f,/50.5f, 0.5f, -0.5f,/6
12、-0.5f, -0.5f, -0.5f,/7; 基準小立方體平移得到一個小立方體Cube0:for(int i=0;i<8;i+)Cube0.CubePointi.p0 = CubePointi.p0 + 1.0f;Cube0.CubePointi.p1 = CubePointi.p1 - 1.0f;Cube0.CubePointi.p2 = CubePointi.p2 - 1.0f;其他26個立方體可通過同樣的方法得到。我認為這是整個程序中最難也是最麻煩的一點。本程序是通過reset_model()這一函數(shù)來構造出整個魔方體的。(3)OpenGL貼圖實現(xiàn)glGenTextures(1,
13、 &texturei),作用是利用載入的圖像生成紋理。glTexCoord2f(GLfloat s, GLfloat t) 函數(shù)用于繪制圖形時指定紋理的坐標。第一個參數(shù)是X坐標,0.0是紋理的左側(cè),0.5是紋理的中點,1.0是紋理的右側(cè)。第二個參數(shù)是Y坐標,0.0是紋理的底部,0.5是紋理的中點,1.0是紋理的頂部。為了將紋理正確的映射到四邊形上,必須將紋理的四個角與四邊形的四個角相對應。否則圖形在四邊形上顯示時將會有錯誤。如果要將一張格式合格的圖片(采用的是256*256的圖片)貼到正方體的一個面上,則需要聯(lián)合使用glTexCoord2f和glVertex3f函數(shù),如下:glBegi
14、n(GL_QUADS);/ 發(fā)布四邊形繪圖指令glTexCoord2f(0.0f, 0.0f); glVertex3fv( CubePoint0.p); glTexCoord2f(1.0f, 0.0f); glVertex3fv( CubePoint1.p);glTexCoord2f(1.0f, 1.0f); glVertex3fv( CubePoint2.p);glTexCoord2f(0.0f, 1.0f); glVertex3fv( CubePoint3.p);這樣可以用同樣的方法在其他5個面貼上相應的紋理圖。這樣就可以得到6個面均貼好紋理圖的小立方體。glBindTexture是Ope
15、nGL核心函數(shù)庫中的一個函數(shù)。作用是選擇生成的紋理。glBindTexture(GL_TEXTURE_2D,texturei),作用是選擇生成的紋理。將texture1中的圖片紋理綁定到程序中,然后就可以畫出6個面均是該紋理的小立方體。這樣畫出的小立方體的六個面上的圖片是相同的。以此類推,便可畫出其他的小立方體。而我在該程序中實現(xiàn)了將小立方體的六個面貼上不同的圖片,原理與上面類似。只需要在給每個面貼圖片時都載入不同的紋理即可。OpenGL貼圖具體流程如下: 圖3(4)魔方整體旋轉(zhuǎn)和平移OpenGL中有給定的函數(shù)來實現(xiàn)圖形的旋轉(zhuǎn)和平移:glTranslatef和glRotatef。其中,glTr
16、anslatef用于平移和確定圖形在界面上的位置。glTranslatef(x,y,z)作用是將圖形平移到坐標為(x,y,z) 的點。其中,x,y分別為屏幕橫向和縱向。z軸為垂直屏幕方向,沿屏幕向外為正方向。屏幕中心默認坐標為(0,0,0)。glRotatef函數(shù)控制魔方整體的旋轉(zhuǎn)。如glRotatef(xrot,1.0f,0.0f,0.0f); 控制魔方圍繞向量為(1,0,0)的直線(即x軸)旋轉(zhuǎn) xrot角度??刂颇Х秸w繞y軸和z軸的旋轉(zhuǎn)可以用同樣的方法實現(xiàn)。綜合以上分析結(jié)果,便可以寫出控制有紋理貼圖的一階立方體的旋轉(zhuǎn)程序。程序運行效果如下圖4: 圖4(5)魔方各個層面的隨機旋轉(zhuǎn)和同步更
17、新索引27個立方體構成3X3魔方矩陣,對每個立方體進行編號。魔方體某層的旋轉(zhuǎn)是基于選中的9個立方體繞魔方體的中心軸變化的。由此定義魔方體每個層面包含的子立方體集合初始索引編號:const BYTE SZP9 = 0,1,2,3,4,5,6,7,8; const BYTE SZS9 = 9,10,11,12,13,14,15,16,17; const BYTE SZM9 = 18,19,20,21,22,23,24,25,26; const BYTE SYM9 = 0,1,2,11,10,9,18,19,20;const BYTE SYS9 = 3,4,5,14,13,12,21,22,23;
18、const BYTE SYP9 = 6,7,8,17,16,15,24,25,26;const BYTE SXM9 =2,3,8,17,12,11,20,21,26;const BYTE SXS9 =1,4,7,16,13,10,19,22,25;const BYTE SXP9 = 0,5,6,15,14,9,18,23,24;預定義好這些層面目的是確定好旋轉(zhuǎn)前后各個子立方體的相對位置。為了記錄魔方體旋轉(zhuǎn)之后各子立方的絕對位置,為此專門定義了同上類似的數(shù)組結(jié)構:BYTE ZP9 = 0,1,2,3,4,5,6,7,8; BYTE ZS9 = 9,10,11,12,13,14,15,16,17;
19、 BYTE ZM9 = 18,19,20,21,22,23,24,25,26; BYTE YM9 = 0,1,2,11,10,9,18,19,20; BYTE YS9 = 3,4,5,14,13,12,21,22,23; BYTE YP9 = 6,7,8,17,16,15,24,25,26; BYTE XM9 =2,3,8,17,12,11,20,21,26; BYTE XS9 = 1,4,7,16,13,10,19,22,25; BYTE XP9 = 0,5,6,15,14,9,18,23,24; 魔方體幾何位置旋轉(zhuǎn)本質(zhì)上就是同步更新各層面內(nèi)的小立方的索引表。如,更新z方向上的第一層的小立方
20、的索引表的部分代碼如下:for( i=0;i<27;i+)for( j=0;j<9;j+)if( is_equal( &Cubei, &Static_Cube SZMj ) ZMk+ = i;is_equal()是判斷旋轉(zhuǎn)后的魔方體Cube的那些子立方Cubei與靜態(tài)的魔方體Static_Cube的SZM層面內(nèi)的子立方重合,找出之后作為ZM的新成員。最終能找到9個子立方作為新成員。而在前面已經(jīng)討論了如何實現(xiàn)立方體圍繞某個軸旋轉(zhuǎn)的問題。對某一層面內(nèi)的9個小立方體均進行旋轉(zhuǎn)操作,然后進行更新索引,就可以得到旋轉(zhuǎn)之后的魔方體。在本程序中我定義了Rotate_XM(),Ro
21、tate_XS(),Rotate_XP(),Rotate_YM(),Rotate_YS(),Rotate_YP(),Rotate_ZM(),Rotate_ZS(),Rotate_ZP()這9個函數(shù),分別控制各個層面的旋轉(zhuǎn)。由于魔方體各個方向上不同層面不能同時旋轉(zhuǎn),所以要在程序中保證各個層面之間的旋轉(zhuǎn)互不沖突。在本程序中我定義了enable_XM_roatate(),enable_XS_roatate(),enable_XP_roatate(),enable_YM_roatate(),enable_YS_roatate(),enable_YP_roatate(),enable_ZM_roatat
22、e(),enable_ZS_roatate(),enable_ZP_roatate()這9個函數(shù),用于判斷某一方向上某一層面是否可以旋轉(zhuǎn)。并且設置了rotX,rotY,rotZ三個全局變量。在以上9個函數(shù)中分別對這3個變量之一進行賦值。在enable_XM_roatate(),enable_XS_roatate(),enable_XP_roatate()三個函數(shù)中分別將rotX賦值為1,2,3,在enable_YM_roatate(),enable_YS_roatate(),enable_YP_roatate()三個函數(shù)中分別將rotY賦值為1,2,3,在enable_ZM_roatate()
23、,enable_ZS_roatate(),enable_ZP_roatate()三個函數(shù)中分別將rotZ賦值為1,2,3,同時保證rotX,rotY,rotZ一次只有一個不為零,這樣就保證了各個層面旋轉(zhuǎn)之間互相不沖突。(6)背景音樂的添加我在該程序中載入了背景音樂,方法比較簡單。#include<mmsystem.h> /提供與多媒體有關的接口#pragma comment(lib, "WINMM.LIB") /導入winmm.lib庫,實現(xiàn)對多媒體編程的支持在所建工程的文件夾中新建名為sound的文件夾,并在其中放入wav格式的音樂愛你一萬年。編寫函數(shù)load
24、sound(),其調(diào)用函數(shù)PlaySound("sound愛你一萬年.wav",NULL,SND_LOOP|SND_ASYNC|SND_FILENAME)加載愛你一萬年背景音樂。(7)定時器的調(diào)用我認為本程序中使用Win32系統(tǒng)的定時器很關鍵,因為程序只能一次執(zhí)行一個線程,而魔方在自身旋轉(zhuǎn)的同時還有各個層面的自由隨機旋轉(zhuǎn),還加上自身的平移等,所以必須用到定時器。在本程序中我用到了3個定時器::SetTimer(hWnd,1,2,NULL),:SetTimer(hWnd,2,1,TimerProc),:SetTimer(hWnd,3,0.5,CubeWalk)。定時器:Set
25、Timer(hWnd,1,2,NULL)的作用是把把其產(chǎn)生的消息加入消息隊列中,由WM_TIMER接收并處理,以實現(xiàn)立方體的旋轉(zhuǎn)。定時器:SetTimer(hWnd,2,1,TimerProc)的回調(diào)函數(shù)是TimerProc。函數(shù)TimerProc用來產(chǎn)生隨機數(shù)。要控制各個層面的隨機旋轉(zhuǎn),一共有18種情況,包括每個方向上每個層面上的正轉(zhuǎn)和反轉(zhuǎn)。故在TimerProc函數(shù)中對隨機數(shù)的情況進行判斷:int r = rand(); if( r%18=0)enable_XM_roatate(1);以上是18中情況中的一種,使魔方的XM層能夠旋轉(zhuǎn),即在enable_XM_roatate(1)中進行如下賦
26、值:rotAngle = 1 rotCount = 0 rotX = 1 rotDirect =1在WM_TIMER中判斷rotX,rotY,rotZ的值并進行相應的旋轉(zhuǎn)操作。本程序中的另外一個定時器:SetTimer(hWnd,3,0.5,CubeWalk)作用是控制魔方的平移。前面已經(jīng)介紹了魔方自身的平移函數(shù)glTranslatef。在程序的最開始定義變量RX和RY,glTranslatef(RX,0.0f,0.0f);ff);則RX和RY代表魔方中心的橫縱坐標。在回調(diào)函數(shù)CubeWalk中對RX和RY值進行處理和改變就可以控制魔方的平移了。定時器的使用及其控制魔方的旋轉(zhuǎn)和平移流程圖如圖5
27、: 圖5 定時器使用流程圖2.3 數(shù)據(jù)結(jié)構分析 在本程序中為了很好的表示一個魔方體并且便于更好地計算,采用結(jié)構體和數(shù)組層層嵌套的形式。定義一個點的結(jié)構體,由3個坐標值構成: typedef struct GLfloat p3; stPoint;定義一個立方體的結(jié)構體,由8個頂點構成:typedef struct stPoint CubePoint8; stCube;定義由27個小立方體構成的數(shù)組:stCube Cube27; 2.4 重要函數(shù)分析 (1)窗口創(chuàng)建 程序中的函數(shù)GLvoid resizeScene(GLsizei width,GLsizei height )目的是重置OpenGL
28、窗口的大小,具體又包含以下幾個函數(shù): glViewport(0,0,width,height)是OpenGL中的視口變化函數(shù),作用是把視景體截取的圖像按照怎樣的高和寬顯示到屏幕上。 glMatrixMode():指定哪一個矩陣是當前矩陣。glMatrixMode設置當前矩陣模式:GL_MODEVIEW,對模型視景矩陣堆棧應用隨后的矩陣操作。GL_PROJECTION,對投影矩陣應用隨后的矩陣操作。 glLoadIdentity()將矩陣清為單位矩陣,避免受其它矩陣操作的干擾,作用是將當前的用戶坐標系的原點移到屏幕中心。 gluPerspective的作用是設置透視投影矩陣,即越遠的東西看起來越
29、小的效果。gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f)45.0f表示將視角設置為45度,(GLfloat)width/(GLfloat)height表示窗口的縱橫比,0.1f表示沿z軸方向的兩裁面之間的距離的近處為0.1,100f表示沿z軸方向的兩裁面之間的距離的遠處為100,即圖像在z軸方向上的坐標必須介于-0.1到-100之間,否則無法顯示出來。(2)初始化在InitGL(GLvoid)中對窗體進行初始化效果:glShadeModel(GL_SMOOTH)作用是啟用陰影平滑。glClearColor(0.5
30、f, 0.0f, 0.0f, 0.5f)作用是設置背景為紅色。glClearDepth(1.0f),作用是設置深度緩存。glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST),作用是做精細的透視修正。loadsound(),作用是導入歌曲愛你一萬年。(3)OpenGL貼圖 glGenTextures(1, &texturei),作用是利用載入的圖像生成紋理。glBindTexture(GL_TEXTURE_2D, texturei),作用是選擇生成的紋理。glTexCoord2f(0.0f,0.0f),作用是設置紋理坐標。glVertex3fv
31、( CubePoint0.p),作用是設置對應的立方體的頂點坐標。glEnable(GL_TEXTURE_2D),作用是啟用紋理映射,此點很關鍵。 如果不用這個函數(shù),圖片將不能貼到立方體的六個面上。(4)旋轉(zhuǎn)和平移在本程序中用到了OpenGL中的平移函數(shù)glTranslatef(x,y,z)和旋轉(zhuǎn)函數(shù)。glTranslatef(x,y,z)表示圖形中心平移到坐標為(x,y,z)的點處。與其類似,glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)表示圖形繞經(jīng)過原點和點(x,y,z)的軸旋轉(zhuǎn)角度angle。方向滿足右手定則。而本程序中
32、控制魔方層面旋轉(zhuǎn)的函數(shù)前面已經(jīng)介紹過,一共有9個函數(shù),分別控制三個方向上各三個層面的旋轉(zhuǎn),旋轉(zhuǎn)方向由全局變量rotDirect是1或-1來決定。(5)消除累計誤差為了避免魔方體層面的旋轉(zhuǎn)之后帶來的累計誤差,在判斷兩個立方體是否重合時,必須消除這種累計誤差。所以判斷兩個點是否重合時,如果兩個點的三個坐標值均相差較小,應該令其分別相等,以消除誤差。 if( fabs(x1 - x2)<1e-1 && fabs(y1-y2)<1e-1 && fabs(z1-z2)<1e-1) pc1->CubePointi.p0 = pc2->CubeP
33、ointj.p0; pc1->CubePointi.p1 = pc2->CubePointj.p1;pc1->CubePointi.p2 = pc2->CubePointj.p2;(6)屏保函數(shù)控制魔方移動是通過定時器Timer3來實現(xiàn)的,而Timer3的回調(diào)函數(shù)為CubeWalk()。在該函數(shù)中,只要控制RX和RY的增減即可。RX和RY為全局變量,初值為零,所以魔方最初的位置是在屏幕的中心。就可以控制魔方每次向斜方向運動。為了實現(xiàn)魔方的反彈效果,需要另外定義兩個全局變量turn_x和turn_y,初值分別為1。且令RX+=(turn_x*0.01)RY+=(turn_
34、y*0.01)當魔方達到邊界時,將turn_x和turn_y中的一個值取相反值,就可以使RX或RY反向增長,從而達到反彈的效果。經(jīng)過試驗,確定屏幕橫向?qū)挻笾聻?6,縱向?qū)挻笾聻?。而判斷魔方達到邊界時不能用“=”來進行判斷,因為會有誤差。為了消除誤差,采用fabs()函數(shù)來進行一定范圍內(nèi)的判斷。if(fabs(RX+8)<0.01|fabs(RX-8)<0.01)else if(fabs(RY+4)<0.01|fabs(RY-4)<0.01) 3.1 成果展示程序整體流程圖分析如下:圖6 程序整體流程圖其實編程不可能一遍成功,我在編程的過程中也遇到了很多問題。(1)我開
35、始將范例程序看懂之后,一氣呵成將三階魔方的程序編寫出來了,但是寫出來的程序只能控制三階魔方的一部分層面旋轉(zhuǎn)。于是我想實現(xiàn)三階魔方任一層面隨機旋轉(zhuǎn)的效果,但是程序?qū)懲陼r候運行結(jié)果卻出人意料之外??梢悦黠@的看到魔方各個層面的旋轉(zhuǎn)發(fā)生沖突,導致魔方產(chǎn)生扭曲。于是我仔細分析產(chǎn)生這種的原因,想了很久,后來想到會不會是寫程序時控制各個層面的旋轉(zhuǎn)的控制量的值有重復,從而產(chǎn)生沖突。然后我就把一個方向上的三個層面旋轉(zhuǎn)的控制量的值改成不同的1,2,3,結(jié)果就可以正常運行了。(2)我在實現(xiàn)三階魔方效果后,就想實現(xiàn)三階魔方的自由反彈效果,我構思的算法自認為是對的,其實也比較簡單,當時控制其反彈的源碼如下:if(RX=
36、-8|RX=8)turn_x=(-turn_x);else if(RY=-4|RY=4)turn_y=(-turn_y);RX+=(turn_x*0.01);RY+=(turn_y*0.01);但是實際運行效果就是與我預想的不一樣。魔方到了邊界,總是不反彈,徑直的跑到屏幕外面去,不見了蹤影。這個問題困擾了我很久,一直得不到解決。我曾經(jīng)想過是不是與屏幕長寬表示錯了有關,但是無論我把屏幕長寬設為多少,魔方總是不反彈。后來我偶然想到,會不會是因為定時器的執(zhí)行周期太短,一次移動距離太短,產(chǎn)生了誤差,所以到達邊界時程序沒有判斷出來。于是我用了fabs函數(shù),給RX和RY設定了一定的誤差范圍,程序竟然可以運行成功了。這說明我的假設是對的。所以以后碰到問題要認真思考,也許靈感就在一瞬間閃現(xiàn)。5 心得和小節(jié) 這段時間以來覺得自己收獲還是挺大的。開始選這個課題是
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 邯鄲燃氣面試題及答案
- 綠色轉(zhuǎn)型面試題及答案
- 頭盔安全教育
- 清明節(jié)傳統(tǒng)文化教育
- 2025年生蠔項目立項申請報告
- 江陰保姆面試題及答案
- 浦發(fā)java面試題及答案
- 綜合管理考試試題及答案
- 計劃觀點面試題及答案
- 胡桃里考試題及答案
- 2023年鍍層和化學覆蓋層技術要求規(guī)范(鋁合金化學導電氧化)
- 南寧市信息化大樓工程建設項目可行性研究報告
- 管 制 刀 具課件
- 生物多樣性保護與建設項目可行性研究報告
- 健康減肥調(diào)脂降糖
- LaTeX科技排版課件
- 2023年河北交通投資集團有限公司招聘筆試題庫及答案解析
- 反向傳播算法課件
- 企業(yè)質(zhì)量安全主體責任
- 南模自招試卷-2012年自主招生
- 數(shù)據(jù)倉庫開發(fā)規(guī)范
評論
0/150
提交評論