本文相當干貨碘梢,包含數(shù)學應(yīng)用技巧蜈块。
前些日子陷谱,老大讓各種小弟學習OpenGL渲染等等,一個主要的大作業(yè)就是用OpenGL繪制會旋轉(zhuǎn)的魔方鸥昏。
大體的思路就是畫三角形面=》兩個三角形面形成一個正方形面=》6個正方形面旋轉(zhuǎn)位移形成小立方體=》多個小立方體位移得到魔方
靜態(tài)的魔方繪制起來沒啥難度塞俱,但是要做隨機方向和層的魔方旋轉(zhuǎn),問題就出來了爬早。
假設(shè)只是2x2x2的2階魔方霉晕,設(shè)上層左上角的方塊編號為1厨内,上層順時針旋轉(zhuǎn)之后,編號1的方塊就到了編號為2的位置唯蝶。每次旋轉(zhuǎn)都需要重新設(shè)置方塊的編號,以便下次旋轉(zhuǎn)修改其模型矩陣遗嗽。
只是2階或者3階魔方的時候粘我,這種編號的重設(shè)可以窮舉解決。但是多階魔方的時候痹换,這種編號重設(shè)就難以找到規(guī)律進行簡化征字。
由此,我找了一種技巧娇豫,無論幾階魔方匙姜,都可以簡單輕松的重設(shè)編號,每次旋轉(zhuǎn)操作都可以找到對應(yīng)的魔方方塊锤躁。
招數(shù)就是方塊編號使用3維向量搁料。以下使用glm與C++代碼做為示例。并且用左手坐標系(z軸向上)系羞。
例如2階魔方中郭计,如果一個小方塊位于上層的右下角,那么給予其一個向量編號pos(1椒振,1昭伸,1),即(x軸正向為右澎迎,y軸正向朝外庐杨,z軸正向朝上)。那么以z軸為軸旋轉(zhuǎn)90度夹供,可以理解為對pos做旋轉(zhuǎn)操作灵份,以數(shù)學進行表達就是用旋轉(zhuǎn)矩陣叉乘pos向量。glm+C++代碼如下:
glm::vec3 pos(1,1,1);
glm::mat4 rotate_mat = glm::rotate(glm::mat4(1.0), glm::radians(90.0), glm::vec3(0,0,1));
pos = glm::vec3(rotate_mat * glm::vec4(pos, 1.0));
代碼運行之后哮洽,得到pos為(1,-1,1)之類的旋轉(zhuǎn)后的方塊編號填渠。不過由于有計算誤差的情況,有時候會得到(0.99999, -0.999999, 1)之類的,此時對每個xyz值做一個浮點值近似判斷就可以了氛什。
每一個方塊存儲一個pos向量作為位置編號莺葫,每次對方塊完成旋轉(zhuǎn)要重設(shè)編號的時候?qū)os做上述向量旋轉(zhuǎn)操作,這樣再次旋轉(zhuǎn)的時候就可以輕松的找到需要旋轉(zhuǎn)的對應(yīng)方塊了枪眉。