本文相當干貨,包含數學應用技巧。
前些日子,老大讓各種小弟學習OpenGL渲染等等,一個主要的大作業就是用OpenGL繪制會旋轉的魔方。
大體的思路就是畫三角形面=》兩個三角形面形成一個正方形面=》6個正方形面旋轉位移形成小立方體=》多個小立方體位移得到魔方
靜態的魔方繪制起來沒啥難度,但是要做隨機方向和層的魔方旋轉,問題就出來了。
假設只是2x2x2的2階魔方,設上層左上角的方塊編號為1,上層順時針旋轉之后,編號1的方塊就到了編號為2的位置。每次旋轉都需要重新設置方塊的編號,以便下次旋轉修改其模型矩陣。
只是2階或者3階魔方的時候,這種編號的重設可以窮舉解決。但是多階魔方的時候,這種編號重設就難以找到規律進行簡化。
由此,我找了一種技巧,無論幾階魔方,都可以簡單輕松的重設編號,每次旋轉操作都可以找到對應的魔方方塊。
招數就是方塊編號使用3維向量。以下使用glm與C++代碼做為示例。并且用左手坐標系(z軸向上)。
例如2階魔方中,如果一個小方塊位于上層的右下角,那么給予其一個向量編號pos(1,1,1),即(x軸正向為右,y軸正向朝外,z軸正向朝上)。那么以z軸為軸旋轉90度,可以理解為對pos做旋轉操作,以數學進行表達就是用旋轉矩陣叉乘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)之類的旋轉后的方塊編號。不過由于有計算誤差的情況,有時候會得到(0.99999, -0.999999, 1)之類的,此時對每個xyz值做一個浮點值近似判斷就可以了。
每一個方塊存儲一個pos向量作為位置編號,每次對方塊完成旋轉要重設編號的時候對pos做上述向量旋轉操作,這樣再次旋轉的時候就可以輕松的找到需要旋轉的對應方塊了。