基于OpenGL的3D旋轉魔方的實現(xiàn)終期報告加源碼
《基于OpenGL的3D旋轉魔方的實現(xiàn)終期報告加源碼》由會員分享,可在線閱讀,更多相關《基于OpenGL的3D旋轉魔方的實現(xiàn)終期報告加源碼(61頁珍藏版)》請在裝配圖網上搜索。
1、華中科技大學電子科學與技術系課程設計報告( 2011- 2012年度第 2 學期)名 稱: 軟件課程設計 題 目: 基于OpenGL的3D旋轉魔方實現(xiàn)院 系: XXXXXX 班 級: XXXXX 學 號: U201014185 學生姓名: X X X 指導教師: X X X 設計周數(shù): XXXX 成 績: 日期: 2012 年 5月 24日1目 錄1課程設計介紹 11.1.內容 1 1.2.目的 11.3.取得的成果 12程序分析 2 2.1. 程序原理 22.1. 程序流程 32.3. 數(shù)據(jù)結構 8 2.4. 重要函數(shù)用法分析 83結果演示與程序分析 93.1. 成果演示 93.2. 程序分
2、析 114編程中遇到的問題125課程設計小結13參考文獻14 基于OpenGL的3D旋轉魔方實現(xiàn)1 課程設計介紹1.1 目的當今計算機技術流行,引領了各行各業(yè)。而程序是計算機的靈魂,因此編程能力對當今的學生而言至關重要。雖然我們在前期已經學習了C語言,但是還只對程序有一些簡單的認識,說實話,是很淺顯的認識。通過本軟件課程設計的學習,可以從整體上對軟件工程和項目有全面的認識。通過此次課程設計,可以鍛煉編程能力,激發(fā)對編程的興趣,同時也能培養(yǎng)良好的編程習慣。這對于個人今后的學習,今后的工作乃至今后的生活都會產生重要的影響。對于國家而言,極大的推動了計算機普及教育,提高了大學生的計算機使用水平,具有
3、重大的意義。1.2 內容(1) 通過此次項目掌握軟件開發(fā)模式,模塊化結構分析以及程序設計流程(2) 學會使用VC+6.0進行編程(3) 掌握有關程序設計的思想,數(shù)據(jù)結構的知識,掌握C語言算法,掌握OpenGL編程知識如貼圖與鍵盤控制(4) 掌握win32編程知識,了解windows程序內部運行機制(5) 初步培養(yǎng)需求分析、軟件測試、調試的能力(6) 在2X2魔方的基礎上,嘗試編寫3X3的魔方,并實現(xiàn)其旋轉1.3 取得的成果在理解Magic2D例子程序的基礎上,借助了Win32平臺進行了一系列調試和學習。在此次項目中,學習了Visual C+6.0軟件開發(fā)環(huán)境,熟練掌握了Win32 Applic
4、ation開發(fā)流程。同時也學習了OpenGL的基本知識,掌握了一些OpenGL的重要技術與重要函數(shù)的使用,編寫了一些簡單的OpenGL程序。參考Magic2D例子流程,我對原程序進行了比較大的修改,并換上了自己的圖片,實現(xiàn)了一個立方體貼六張不同的圖片,并編寫出了自己的2X2魔方程序。根據(jù)相似度分析,成功的編寫出了3X3旋轉魔方,并自己設計了算法,實現(xiàn)了各個層面的轉動,轉動效果很完美。同時,為了增加程序的娛樂效果,我加入了歌曲最炫民族風,雖然很簡單,不過感覺非常實用且有趣。2 程序分析2.1 程序原理 (1)OpenGLOpenGL是一個開放的三維圖形軟件包,它獨立于窗口系統(tǒng)和操作系統(tǒng),以它為基
5、礎開發(fā)的應用程序可以十分方便地在各種平臺間移植;OpenGL可以與Visual C+緊密接口,便于實現(xiàn)機械手的有關計算和圖形算法,可保證算法的正確性和可靠性;OpenGL使用簡便,效率高。本設計是在Visual C+6.0開發(fā)環(huán)境下,使用OpenGL(Open Graphics Library)函數(shù)庫,繪制魔方并實現(xiàn)魔方的繪制、隨機旋轉、貼圖以及鍵盤控制等功能。采用基本圖形的繪圖函數(shù)及定位函數(shù),添加相應紋理來實現(xiàn)魔方模型的繪制。通過讀取載入BMP文件,應用紋理貼圖技術來完成對魔方旋轉面的處理。 (2)模型的旋轉首先對立方體進行建模。一個立方體由8個點組成,8個點組成6個面片,對立方體的幾何操作
6、本質上就是對這6個平面的操作(繪制、紋理、旋轉和平移等)。點的索引號確定后,每個面片也就確定了,如0,1,2,3四個點構成Z向正投影面。立方體在空間的旋轉,歸根到底是其頂點的旋轉,如空間點(x, y, z)繞Z軸旋轉a對應的旋轉矩陣:cosa sina-sina cosa一個立方體pCube繞Z軸旋轉a后對應的坐標變化為:for( int i=0;iCubePointi.p0; y= pCube-CubePointi.p1; pCube-CubePointi.p0 = x*cosa - y*sina; pCube-CubePointi.p1 = x*sina + y*cosa;其它軸的旋轉類似
7、。由于魔方體層面的旋轉是90,在某個層面內一個子立方體Ci會被另外一個Cj完全替換,因此旋轉后必須同步更新魔方體Cube各層面內包含的子立方的索引號。為了簡化算法,只需查找旋轉后Cubei在Static_Cube中對應的小立方編號j與i的位置匹配。 2.2 程序的流程 通過分析,整個程序大致可以分為6個子功能模塊(1) Win32應用程序框架WinMain主函數(shù)是所有Win32程序的入口點。在WinMain函數(shù)里實現(xiàn)Window是窗體的建立和消息循環(huán),在消息循環(huán)中實現(xiàn)鍵盤、鼠標輸入事件處理響應,具體內容可參考VC程序參考手冊。在本課程程序中,不僅要創(chuàng)建Window窗體,而且構建OpenGL設備
8、繪圖環(huán)境。 Window窗體創(chuàng)建步驟:l 窗體類注冊:RegisterClassl 設置顯示分辨率:ChangeDisplaySettingsl 設置窗體大?。篈djustWindowRectExl 創(chuàng)建窗體:CreateWindowExOpenGL繪圖環(huán)境搭建:l 獲取設備繪圖環(huán)境(DC,DeviceContext):hDC=GetDC(hWnd)l 選擇繪圖環(huán)境像素格式:ChoosePixelFormat(hDC,&pfd),其中pfd為像素格式描述符,如果設置不對,OpenGL繪圖失敗,看不到正確的顯示結果。l 設置繪圖環(huán)境像素格式:SetPixelFormat(hDC,PixelFor
9、mat,&pfd)l 獲取OpenGL繪圖環(huán)境:hRC =wglCreateContext(hDC)l 設置OpenGL繪圖環(huán)境:wglMakeCurrent(hDC,hRC)(2)空間建模得到3階魔方 顯然,要建立3X3的魔方必須首先建立單個魔方的模型,然后通過對單個立方體進行平移從而得到3X3的魔方。 平移單個立方體通過reset_model( )函數(shù)中的語句實現(xiàn) for(i=0;i8;i+)Cube0.CubePointi.p0 = CubePointi.p0-2.0f ;Cube0.CubePointi.p1 = CubePointi.p1-2.0f ;Cube0.CubePointi
10、.p2 = CubePointi.p2+2.0f;上述代碼只得到了編號為0的立方體,其他編號的立方體同理可以得到構成2X2的魔方需要8個立方體,構建3X3的魔方則需要27個立方體。根據(jù)2階魔方的一些方法,類比到3階魔方。則首先對魔方的立方體進行編號,然后通過編號得到魔方各層所包含立方體的編號。其中編號為BYTE ZP9 = 0,1,2,3,4,5,6,7,8; /z軸方向正向一層BYTE ZZ9 = 9,10,11,12,13,14,15,16,17; /z軸方向中間一層BYTE ZM9 = 18,19,20,21,22,23,24,25,26; /z軸方向負向一層BYTE YM9 = 0,1
11、,2,11,10,9,18,19,20; /y軸方向負向一層BYTE YZ9 = 3,4,5,14,13,12,21,22,23; /y軸方向中間一層BYTE YP9 = 6,7,8,17,16,15,24,25,26; /y軸方向正向一層BYTE XM9 = 2,3,8,17,12,11,20,21,26; /x軸方向正向一層BYTE XZ9 = 1,4,7,16,13,10,19,22,25; /x軸方向中間一層BYTE XP9 = 0,5,6,15,14,9,18,23,24; /x軸方向負向一層(3)OpenGL紋理貼圖以下是紋理貼圖的流程,其中實現(xiàn)了一個立方體貼六張圖片 GLuint
12、 texture6創(chuàng)建紋理存儲AUX_RGBImageRec* TextureImage6; 創(chuàng)建紋理的存儲空間 TextuteImagei=auxDIBImageLoad(“picture/y1.bmp)調用此函數(shù)六次載入六張不同的圖片glGenTexTures(1,&texturei)用載入的圖像生成六個紋理glBindTextures(GL_TEXTURE_2D,texturei選擇生成的紋理glBegin(GL_QUADS);glTexCoord(0.0f,0.0f);glVertex3fv(CubePoint0.p);glEnd();每次選擇不同的紋理,然后利用OpenGL是狀態(tài)機的
13、性質,可以給每個面貼上不同的圖片(4)同步更新索引在整個程序中,同步更新索引所涉及到的算法可以算是最核心的了。當然,你也可以讓每層每個周期轉動360度,這樣就不需要動態(tài)更新索引了,因為每次轉動前后,立方體的相對坐標位置并沒有改變。但是這樣得到的旋轉效果并不好,因為這并沒有考慮到魔方旋轉的所有情況,每次旋轉后魔方都沒有被打亂。由于涉及到動態(tài)刷新索引,于是按照常理定義一個靜態(tài)的魔方與動態(tài)的魔方進行比較。類似動態(tài)魔方的編號可以得到靜態(tài)魔方的編號。const BYTE SZP9 = 0,1,2,3,4,5,6,7,8; /z軸方向正向一層const BYTE SZZ9 = 9,10,11,12,13,
14、14,15,16,17; /z軸方向中間一層const BYTE SZM9 = 18,19,20,21,22,23,24,25,26; /z軸方向負向一層const BYTE SYM9 = 0,1,2,11,10,9,18,19,20; /y軸方向負向一層const BYTE SYZ9 = 3,4,5,14,13,12,21,22,23; /y軸方向中間一層const BYTE SYP9 = 6,7,8,17,16,15,24,25,26; /y軸方向正向一層const BYTE SXM9 = 2,3,8,17,12,11,20,21,26; /x軸方向正向一層const BYTE SXZ9
15、= 1,4,7,16,13,10,19,22,25; /x軸方向中間一層const BYTE SXP9 = 0,5,6,15,14,9,18,23,24; /x軸方向負向一層然后編寫一個函數(shù)int is_equal(stCube *pc1,stCube *pc2)判斷兩個立方體是否重合,這個函數(shù)的算法就是比較立方體所有頂點的坐標是否相同。最后一步編寫函數(shù)void Update_Cube_index(),由于魔方轉動情況總體上有九種情況,則該函數(shù)必須編寫九塊功能類似的代碼,現(xiàn)在只列出X軸負向一層刷新索引的算法。int i,j,k=0;k =0 ;for( i=0;i9;i+) for( j=0;
16、j27;j+) if( is_equal( &Cubej, &Static_Cube SZMi ) )ZMk+ = j; (5)魔方的旋轉以及鍵盤控制對魔方的平移魔方層面的旋轉已經在前面介紹,此處除了層面旋轉還有魔方的整體旋轉。只需調用庫函數(shù)即可即可。glRotatef(xrot,1.0,0.0,0.0); /使魔方繞x軸轉動xrot度glRotatef(yrot,0.0,1.0,0.0); /使魔方繞y軸轉動yrot度glRotatef(zrot,0.0,0.0,1.0); /使魔方繞z軸轉動zrot度(6)定時器對魔方層面旋轉的控制 為了控制魔方的轉動,首先定義了函數(shù)void enable
17、_X_roatate(int direction),void enable_Y_roatate(int direction),void enable_Z_roatate(int direction)以確定旋轉軸和旋轉方向,同時定義了void Rotate_X(int ii),void Rotate_Y(int ii),void Rotate_Z(int ii)來指定是哪一層的旋轉。然后定義兩個計時器Time1和Time2,其中Timer1的消息由WM_TIMER接收并處理,以實現(xiàn)立方體的旋轉。Timer2的消息由TimerProc函數(shù)處理,用于生成控制量以控制旋轉軸和旋轉方向。流程如圖:魔方的
18、層面旋轉r除6得到控制參數(shù)r=rand()得到隨機數(shù)rTimer2cs除3的余數(shù)得到控制參數(shù)Timer1實現(xiàn)旋轉cs=rand()得到隨機數(shù)cs(7)背景音樂的添加 為了程序有更豐富的效果,我添加了歌曲最炫民族風,方法也很簡單。 #include /提供與多媒體有關的接口 #pragma comment(lib, WINMM.LIB) /導入winmm.lib庫,實現(xiàn)對多媒體編程的支持 編寫函數(shù)loadsound(),其調用函數(shù)PlaySound(sound最炫民族風.wav,NULL,SND_LOOP|SND_ASYNC|SND_FILENAME)加載最炫民族風味背景音樂。(8)窗口文字的添
19、加 為了添加自己的信息,我在程序窗口中加了文字void drawString(const char* str),實現(xiàn)添加英文字符。void drawCNString(const char* str)實現(xiàn)添加中文字符void selectFont(int size, int charset, const char* face),實現(xiàn)變換字體 2.3 數(shù)據(jù)結構本程序定義了記錄魔方體每個小塊編號的數(shù)組Cubei及相應的定態(tài)數(shù)組Static_Cube,用來對魔方體變化過程中的相對位置進行索引及重新定位。定義了立方體記錄頂點位置的數(shù)組CubePointi及相應靜態(tài)數(shù)組stPoint CubePointi
20、,用來確定魔方體的旋轉,因為旋轉歸根結底是其頂點位置的旋轉。定義了用來記錄魔方體各個面上子塊編號的數(shù)組ZP/ZZ/ZM,YP/YZ/YM,XP/XZ/XM,及其對應靜態(tài)數(shù)組。定義了數(shù)組TextureImagei來接收紋理。 2.4 重要函數(shù)用法分析(1)窗口創(chuàng)建GLvoid resizeScene(GLsizei width,GLsizei height )這個函數(shù)的目的是重置OpenGL窗口的大小,具體又包含以下五個函數(shù)glViewport(0,0,width,height);glViewport是OpenGL中視口變化函數(shù),根據(jù)窗口的實時變化重繪窗口,它負責把視景體截取的圖像按照怎樣的高和
21、寬顯示到屏幕上。glMatrixMode(GL_PROJECTION)、glMatrixMode(GL_MODELVIEW) 這兩個函數(shù)原型都是glMatrixMode函數(shù)。glMatrixMode這個函數(shù)其實就是要指定操作的是哪種矩陣。如果參數(shù)是GL_PROJECTION,這個是投影的意思,如果參數(shù)是GL_MODELVIEW,這個是對模型視景的操作,用于對三維場景中坐標系的變換操作。glLoadIdentity()glLoadIdentity該函數(shù)的功能是將當前的用戶坐標系的原點移到了屏幕中心,就像一個復位操作gluPerspective(45.0f,(GLfloat)width/(GLfl
22、oat)height,0.1f,100.0f)gluPerspective的作用是設置透視投影矩陣,意味著越遠的東西看起來越小。45.0f表示將視角設置為45度,(GLfloat)width/(GLfloat)height表示窗口的縱橫比,0.1f表示沿z軸方向的兩裁面之間的距離的近處為0.1,100f表示沿z軸方向的兩裁面之間的距離的遠處為100 (2)初始化操作 glShadeModel(GL_SMOOTH),作用是啟用陰影平滑。 glClearColor(0.0f, 0.0f, 0.0f, 0.5f),作用是將背景設置為黑色。 glClearDepth(1.0f),作用是設置深度緩存。
23、glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST),作用是做精細的透視修正。 loadsound(),作用是導入歌曲最炫民族風。 (3)OpenGL貼圖 glGenTextures(1, &texturei),作用是利用載入的圖像生成紋理。 glBindTexture(GL_TEXTURE_2D, texturei),作用是選擇生成的紋理。 glTexCoord2f(0.0f,0.0f),作用是設置紋理坐標。 glEnable(GL_TEXTURE_2D),作用是啟用紋理映射,此點很關鍵。 (4)平移與旋轉 glTranslatef(x, y, z
24、) 平移函數(shù)。表示相對于當前所在的屏幕位置沿著 X, Y 和 Z 軸移動x,y和z個單位。glRotatef(angle, x, y, z)旋轉函數(shù)。與glTranslatef(x, y, z)類似,glRotatef(angle, x, y, z)也是對坐標系進行操作。旋轉軸經過原點,方向為(x,y,z),旋轉角度為angle,方向滿足右手定則。(5)添加窗口文字void drawString(const char* str),實現(xiàn)添加英文字符。void drawCNString(const char* str)實現(xiàn)添加中文字符void selectFont(int size, int ch
25、arset, const char* face),實現(xiàn)變換字體3 結果演示與程序分析3.1成果展示魔方體旋轉對魔方定位對魔方進行編號3.2程序分析紋理綁定循環(huán)調用生成紋理 3X3魔方有27個小塊,對每個小塊分別進行編號。先畫出一個子塊,經過向相應方向的平移,獲得完整的魔方體。 魔方由函數(shù)glTranslatef(float x,float y,float z)定位,再由函數(shù)glRotate(float angle,float x,float y,float z)進行旋轉,然后由函數(shù)glBindTexture(GLenum target,GLunit textureName)進行紋理與相應面的綁
26、定(紋理已由glGenTextures()函數(shù)來產生),最后再用函數(shù)glBegin(GL_QUADS)畫出正方面,從而描繪出了魔方的一個小面。循環(huán)調用就可以繪制出的魔方。循環(huán)調用程序的紋理綁定和旋轉過程就實現(xiàn)了魔方體的旋轉變化。4.編程中遇到的問題 在對2X2魔方理解的基礎上,我經過自己的摸索終于在末期做出了自己的3階魔方。其中,遇到了很多問題,不過都被我解決了。以下是我認為的比較重要的問題(1)在編寫判斷兩個立方體是否重合的函數(shù)時,開始我沒有消除累計誤差。說實話,當時我對這個程序并不是很了解。沒有加入這個功能,程序運行結果如下:剛開始時還比較正常,運行一段時間后,魔方錯位了。想了很久,看了指
27、導書才知道原來還差消除累計誤差這個功能。其實,這也很好解釋。因為我們編寫的旋轉函數(shù)涉及到計算cosa以及sina的值,而計算機計算這些值是不是很準確的。在一個旋轉周期中,要計算180次cosa和sina的值,因此誤差會被放大,則消除累計誤差成了必須。只需判斷兩個數(shù)在一定誤差范圍內相等即可。 (2)魔方循環(huán)控制算法的設計中,我遇到了前所未有的問題。單獨編寫控制最外面一層或是中間一層旋轉的函數(shù)確實比較簡單,但是如何實現(xiàn)一個實現(xiàn)外層和中間一層同時都可旋轉的魔方還是很有難度的,這涉及到如何合理調度的問題。在多方調試后,我想到了一個很好的算法,就是再引入一個控制變量cs,可是變量應該選擇在哪里賦值呢?剛
28、開始我毫不猶豫的就選擇在TimerProc函數(shù)里面賦值,可是一下子就出錯了。后來我將Timer2的定時時間設置為1800ms,目的是等于Timer1的180倍,以實現(xiàn)轉一個周期cs重新賦值一次,可結果表明我再次錯了。因為轉動的延遲,所以轉動一個周期所需時間是不定的,但肯定不等于1800ms。在重新閱讀一遍程序后,我發(fā)現(xiàn)在void Rotate_ZM()函數(shù)中有轉動一個周期后的初始化操作,受到啟發(fā)后,我于是將cs的賦值移到了這個函數(shù)中,運行了觀察很久后都沒有出錯,果然成功了。(3)編程過程中還有一些小問題,不過只要是因為C語言編程的一些知識都忘記了,于是我又重新復習了一下C語言的有關知識,果然編
29、起來得心應手多了。5.課程設計小結編程是一件急需細心和耐心的事,剛開始調試過程中遇到了很多弄不清楚原因的報錯現(xiàn)象,但是經過不斷地修改,那些問題也都沒有了。一開始寫3X3程序的時候,為了避免犯錯誤,我是沒有加旋轉的,只是建了一個魔方的模型并將其繪制出。 加了旋轉函數(shù)后果然遇到了一些問題,旋轉過程中有時候會出現(xiàn)折疊和重疊現(xiàn)象,經過仔細的檢查修改,發(fā)現(xiàn)原因是在調用旋轉函數(shù)時,有部分子塊的運動沒有寫入函數(shù),于是問題得到了部分解決。但是隨后編寫循環(huán)控制算法遇到了很大問題,剛開始都弄煩了,但是休息一段時間后,沉下心來仔細思考,我想到了非常好的控制算法,終于問題全部解決了。 這次課程設計,我確實學到了很多。
30、不僅有提升編程能力,而且也學習到了很多做人的道理。剛開始入手這個項目,感覺壓力非常大,因為我之前在3D設計方面還是零基礎,OpenGL讓我感覺是那么的復雜。隨后,我掌握了OpenGL貼圖技術,并充分利用OpenGL的特性實現(xiàn)了一個立方體貼六張不同的圖片。在我以為實現(xiàn)了一個旋轉立方體后,實現(xiàn)2階魔方就難度不大時,我再次因為我自己的無知而停下了腳步。閱讀完老師的代碼,總感覺思維很混亂。于是此后很久都沒有進展。一段時間過后,當我再次仔細閱讀這些算法時,我終于將它們完美的串接了起來,實現(xiàn)了2階魔方。由2階魔方到3階魔方是類似的,但是循環(huán)控制算法要難一些。好在我再次編寫出來了很好的控制算法,感覺效果很好
31、總的來說總的來說,本次軟件課程設計,對我來說收獲不小。不僅復習了C語言知識,也對編程及3D設計產生了一定的興趣,分析問題和解決問題的能力也得到了不小的提高。而且,我也學到了很多人生的道理。在做一件看似很難的事時,我們要有一個總體的框架,不要有畏難心理。靜下心來,沉著的分析問題,問題總會迎刃而解的。因此,成功的關鍵在于你是否擁有這樣的心理。參考文獻1孫鑫 VC+深入詳解 第三版 北京 電子工業(yè)出版社 2007年 1-262楊柏林,陳根浪,徐靜 OpenGL編程精粹 第三版 北京 機械工業(yè)出版社 2010年 1-1213周純杰,劉正林,何頂新,周凱波 標準C語言程序設計及應用 第二版 武漢 華中科
32、技大學出版社 2008年 1-2634Dave Shreiner,The Khronons OpenGLARB Working Group OpenGL編程指南 第七版 北京 機械工業(yè)出版社 2010年 21-328 附上源碼第一個文件-頭文件MoFang.h#ifndef _MO_FANG_H_#define _MO_FANG_H_#include / windows的頭文件#include #include / 包含OpenGL核心庫#include / 包含OpenGL實用庫#include / 包含OpenGL輔助庫#include / 包含數(shù)學函數(shù)庫#define PI2 6.283
33、1853f #define CYCLE_COUNT 90#define MAX_CHAR 128 /用于在窗口顯示文字而定義的常數(shù)#define FRONT 0#define BACK 1#define LEFT 2#define RIGHT 3#define TOP 4#define BOTTOM 5typedef struct GLfloat vx,vy,vz;CubeVertex;typedef struct GLfloat p3;stPoint;typedef struct stPoint CubePoint8;stCube;void reset_model(); void Rotat
34、e_ZM();void Rotate_ZZ();void Rotate_ZP();void Rotate_XM();void Rotate_XZ();void Rotate_XP();void Rotate_YM();void Rotate_YZ();void Rotate_YP();void Rotate_Z(int ii);void Rotate_Y(int ii);void Rotate_X(int ii);void enable_X_roatate(int direction);void enable_Y_roatate(int direction);void enable_Z_roa
35、tate(int direction);void selectFont(int size, int charset, const char* face);void drawCNString(const char* str);void drawString(const char* str);extern stCube Cube27;extern int rotAngle;extern int rotCount;extern int rotX,rotY,rotZ; extern GLfloat Vx,Vy;#endif 第二個文件MoFang.cpp/* *這個cpp文件包含三階魔方變換的常規(guī)函數(shù)
36、 * 作者為張世清 學號U201014185 *華中科技大學電子系集成1001班 2012.5.19 *當然成果還離不開組員徐兮、雷韋拉以及何兆華的支持 */加入自己編寫的魔方頭文件,其中包含一些變量定義與函數(shù)聲明#include MoFang.h /對立方體各頂點編號static stPoint CubePoint8= -1.0f, -1.0f, 1.0f, /0 1.0f, -1.0f, 1.0f , /1 1.0f, 1.0f, 1.0f , /2 -1.0f, 1.0f, 1.0f, /3-1.0f, -1.0f, -1.0f, /4 -1.0f, 1.0f, -1.0f, /51.0
37、f, 1.0f, -1.0f, /6 1.0f, -1.0f, -1.0f, /7 ;extern int cs;stCube Cube27; /定義一個3階魔方stCube Static_Cube27; /定義一個靜態(tài)的3階魔方/旋轉控制int rotAngle = 1; /旋轉角度int rotCount; /一個旋轉周期內旋轉次數(shù) CYCLE_COUNT = 90/rotAngle;int rotX,rotY,rotZ; /指定那個軸旋轉int rotDirect=1; /正反向旋轉/對當前魔方各個立方體進行編號BYTE ZP9 = 0,1,2,3,4,5,6,7,8; /z軸方向正向一
38、層BYTE ZZ9 = 9,10,11,12,13,14,15,16,17; /z軸方向中間一層BYTE ZM9 = 18,19,20,21,22,23,24,25,26; /z軸方向負向一層BYTE YM9 = 0,1,2,11,10,9,18,19,20; /y軸方向負向一層BYTE YZ9 = 3,4,5,14,13,12,21,22,23; /y軸方向中間一層BYTE YP9 = 6,7,8,17,16,15,24,25,26; /y軸方向正向一層BYTE XM9 = 2,3,8,17,12,11,20,21,26; /x軸方向正向一層BYTE XZ9 = 1,4,7,16,13,10
39、,19,22,25; /x軸方向中間一層BYTE XP9 = 0,5,6,15,14,9,18,23,24; /x軸方向負向一層/對靜態(tài)魔方各個立方體進行編號const BYTE SZP9 = 0,1,2,3,4,5,6,7,8; /z軸方向正向一層const BYTE SZZ9 = 9,10,11,12,13,14,15,16,17; /z軸方向中間一層const BYTE SZM9 = 18,19,20,21,22,23,24,25,26; /z軸方向負向一層const BYTE SYM9 = 0,1,2,11,10,9,18,19,20; /y軸方向負向一層const BYTE SYZ9
40、 = 3,4,5,14,13,12,21,22,23; /y軸方向中間一層const BYTE SYP9 = 6,7,8,17,16,15,24,25,26; /y軸方向正向一層const BYTE SXM9 = 2,3,8,17,12,11,20,21,26; /x軸方向正向一層const BYTE SXZ9 = 1,4,7,16,13,10,19,22,25; /x軸方向中間一層const BYTE SXP9 = 0,5,6,15,14,9,18,23,24; /x軸方向負向一層void Rotate(stCube *pCube,float angle,float x0,float y0,
41、float z0); /聲明旋轉函數(shù)/判斷兩個立方體是否重合,即判斷兩個立方體所包含的所有頂點坐標是否相同int is_equal(stCube *pc1,stCube *pc2) float x1,x2,y1,y2,z1,z2; int isFind = 0; for( int i=0;iCubePointi.p0; y1 = pc1-CubePointi.p1; z1 = pc1-CubePointi.p2; isFind = 0; for(int j=0;jCubePointj.p0; y2 = pc2-CubePointj.p1; z2 = pc2-CubePointj.p2; if(
42、 fabs(x1 - x2)1e-1 & fabs(y1-y2)1e-1 & fabs(z1-z2)CubePointi.p0 = pc2-CubePointj.p0; /消除累計誤差 pc1-CubePointi.p1 = pc2-CubePointj.p1; pc1-CubePointi.p2 = pc2-CubePointj.p2; isFind = 1; break; if( isFind = 0) return 0; return 1;/旋轉之后,查找當前旋轉面里面包含新的角點void Update_Cube_index()int i,j,k=0; /根據(jù)逐一判斷立方體是否重合來更新
43、每一層所包含的立方體的索引,總共三個方向有九層k =0 ;for( i=0;i9;i+) for( j=0;j27;j+) if( is_equal( &Cubej, &Static_Cube SZMi ) )ZMk+ = j;k=0;for(i=0;i9;i+)for(j=0;j27;j+)if(is_equal( &Cubej, &Static_Cube SZZi )ZZk+=j;k = 0;for( i=0;i9;i+)for( j=0;j27;j+)if( is_equal( &Cubej , &Static_Cube SZPi ) )ZPk+ = j; k =0 ;for( i=0;
44、i9;i+) for( j=0;j27;j+) if( is_equal( &Cubej, &Static_Cube SXMi ) ) XMk+ = j; k =0 ;for( i=0;i9;i+) for( j=0;j27;j+)if( is_equal( &Cubej, &Static_Cube SXZi ) )XZk+ = j;k = 0;for( i=0;i9;i+) for(j=0;j27;j+) if( is_equal( &Cubej, &Static_Cube SXPi ) ) XPk+ = j; k =0 ;for( i=0;i9;i+) for(j=0;j27;j+)if(
45、 is_equal( &Cubej, &Static_Cube SYMi ) )YMk+ = j;k =0 ;for( i=0;i9;i+) for(j=0;j27;j+)if( is_equal( &Cubej, &Static_Cube SYZi ) )YZk+ = j; k = 0;for( i=0;i9;i+) for( j=0;j27;j+) if( is_equal( &Cubej, &Static_Cube SYPi ) ) YPk+ = j; /z軸負向一層繞著z軸轉void Rotate_ZM() for(int i=0;i9;i+) Rotate(&Cube ZMi ,ro
46、tAngle*rotDirect, 0.0,0.0, 1.0);/轉180度后重新更新立方體索引 if( rotCount+=CYCLE_COUNT)cs=rand()%3; /每轉一個周期后重新對cs賦值Update_Cube_index();rotAngle = 0;rotZ = 0;/z軸中間一層繞著z軸轉void Rotate_ZZ() for(int i=0;i9;i+) Rotate(&Cube ZZi ,rotAngle*rotDirect, 0.0,0.0, 1.0);/轉180度后重新更新立方體索引 if( rotCount+=CYCLE_COUNT)cs=rand()%3;
47、 /每轉一個周期后重新對cs賦值Update_Cube_index();rotAngle = 0;rotZ = 0;/z軸正向一層繞著z軸轉void Rotate_ZP() for(int i=0;i9;i+) Rotate(&Cube ZPi ,rotAngle*rotDirect, 0.0,0.0, 1.0);/轉180度后重新更新立方體索引 if( rotCount+=CYCLE_COUNT)cs=rand()%3; /每轉一個周期后重新對cs賦值Update_Cube_index();rotAngle = 0;rotZ = 0;/x軸負向一層繞著x軸轉void Rotate_XM()
48、for(int i=0;i9;i+) Rotate(&Cube XMi ,rotAngle*rotDirect, 1.0,0.0, 0.0);/轉180度后重新更新立方體索引if( rotCount+=CYCLE_COUNT)cs=rand()%3; /每轉一個周期后重新對cs賦值Update_Cube_index();rotAngle = 0;rotX = 0;/x軸中間一層繞著x軸轉void Rotate_XZ() for(int i=0;i9;i+) Rotate(&Cube XZi ,rotAngle*rotDirect, 1.0,0.0, 0.0);/轉180度后重新更新立方體索引i
49、f( rotCount+=CYCLE_COUNT)cs=rand()%3; /每轉一個周期后重新對cs賦值Update_Cube_index();rotAngle = 0;rotX = 0;/x軸正向一層繞著x軸轉void Rotate_XP() for(int i=0;i9;i+) Rotate(&Cube XPi ,rotAngle*rotDirect, 1.0,0.0, 0.0);/轉180度后重新更新立方體索引if( rotCount+=CYCLE_COUNT)cs=rand()%3; /每轉一個周期后重新對cs賦值Update_Cube_index();rotAngle = 0;ro
50、tX = 0;/y軸負向一層繞著y軸轉void Rotate_YM() for(int i=0;i9;i+) Rotate(&Cube YMi ,rotAngle*rotDirect, 0.0,1.0, 0.0);/轉180度后重新更新立方體索引if( rotCount+=CYCLE_COUNT)cs=rand()%3; /每轉一個周期后重新對cs賦值Update_Cube_index();rotAngle = 0;rotY = 0;/y軸中間一層繞著y軸轉void Rotate_YZ() for(int i=0;i9;i+) Rotate(&Cube YZi ,rotAngle*rotDir
51、ect, 0.0,1.0, 0.0);/轉180度后重新更新立方體索引if( rotCount+=CYCLE_COUNT)cs=rand()%3; /每轉一個周期后重新對cs賦值Update_Cube_index();rotAngle = 0;rotY = 0;/y軸正向一層繞著y軸轉void Rotate_YP() for(int i=0;i9;i+) Rotate(&Cube YPi ,rotAngle*rotDirect, 0.0,1.0, 0.0);/轉180度后重新更新立方體索引if( rotCount+=CYCLE_COUNT)cs=rand()%3; /每轉一個周期后重新對cs賦值Update_Cube_index();rotAngle = 0;rotY = 0;/通過控制量ii來確定是那一層面繞Z軸轉動void Rotate_Z(int ii)switch(ii)case 0: Rotate_ZP();
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
5. 裝配圖網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。