旋轉

2016-02-27 38 views
2

我有一個rubiks立方體狀的拼圖,我嘗試使用three.js所中的WebGL模型:旋轉

enter image description here

每兩色心能旋轉。當他們旋轉時,他們沿着旋轉將他們周圍的所有碎片帶走。例如,如果我們旋轉橙藍色的中心,這是發生了什麼:

rotating around Orange-Blue Center

當你完成一個旋轉,一切都排隊:

enter image description here

但是,現在當我嘗試旋轉橙白色的中心,我得到它在第一次旋轉後從橙 - 藍中心繼承的兩件的奇怪行爲:

enter image description here

我期望他們像其他棋子一樣旋轉,但他們旋轉的方式不同。

我使用three.js所的Object3D.rotateOnAxis()函數做我轉:

function rotate (center, distance) { 
    var axis = center.axis; 
    center.model.rotateOnAxis (axis, distance); 
    for (var i in center.stickers) { 
     center.stickers[i].rotateOnAxis (axis, distance ); 
    } 

    for (var i in center.children) { 
     center.children[i].model.rotateOnAxis (axis, distance); 

     //Note: the stickers are just the colored faces 
     for (var s in center.children[i].stickers) { 
      center.children[i].stickers[s].rotateOnAxis (axis, distance); 
     } 
    } 
} 

這裏是我的按鍵代碼的樣子:

function showCube() { 
    //set stuff up, then... 

    count = 0; 
    parent.onkeypress = function(event) { 
     if (count < 6) { 
      rotate(blocks.centers [ "BO" ], Math.PI/6); 

      count++; 

      if (count == 6) { 
       moveFace (blocks, "O1", "OY", "BW"); 
       moveFace (blocks, "O2", "OW", "BY"); 

       moveFace (blocks, "B1", "BW", "OY"); 
       moveFace (blocks, "B2", "BY", "OW"); 

       moveCorner (blocks, "BOW", "OW", "OY"); 
       moveCorner (blocks, "BOW", "BW", "BY"); 

       moveCorner (blocks, "BOY", "OY", "OW"); 
       moveCorner (blocks, "BOY", "BY", "BW"); 
      } 

     } else { 
      rotate(blocks.centers [ "OW" ], Math.PI/6); 
     } 
    } 
} 

function moveFace (blocks, child, oldParent, newParent) { 
    var index = blocks.centers [ oldParent ].children.indexOf (blocks.faces [ child ]); 
    blocks.centers [ oldParent ].children.splice (index, 1); 
    blocks.centers [ newParent ].children.push (blocks.faces [ child ]); 
} 

function moveCorner (blocks, child, oldParent, newParent) { 
    var index = blocks.centers [ oldParent ].children.indexOf (blocks.corners [ child ]); 
    blocks.centers [ oldParent ].children.splice (index, 1); 
    blocks.centers [ newParent ].children.push (blocks.corners [ child ]); 
} 

有趣的是,獲得藍橙黃角要正確旋轉,我需要圍繞BO矢量和OW矢量之間的差異進行旋轉。

也就是說:

  • 藍橙軸是歸一化的向量:(0,1,1)
  • 橙白色軸是歸一化的向量:(1,0, 1)
  • 第一次旋轉完成後,如果我嘗試旋轉BOY 角(1,0,1)的法線,我會得到 中顯示的行爲圖片。但是,如果我試着旋轉它(0,1,1) - (1,0,0,1),即(-1,1,0),我會得到所需的行爲。

我不明白髮生了什麼事。你能幫我更新我的旋轉功能嗎,這樣我就能得到我想要的行爲,而不必保留一段經歷過的旋轉過長的列表?

我懷疑我做了第一次旋轉之後,我需要告訴它的旋轉狀態「零」而不會引起任何動作,但我不太確定該怎麼做,或者如果這是正確的方法。 http://joshuad.net/clover-cube/so-question/

感謝:

您可以用的東西在這裏玩!

回答

0

我通過改變我的旋轉方法此固定它:

function rotate (center, distance) { 
    var axis = center.axis; 
    center.model.rotateOnAxis (axis, distance); 
    applyStatesToMatrixDirectly (center.model); 

    for (var stickerIndex in center.stickers) { 
     center.stickers[stickerIndex].rotateOnAxis (axis, distance ); 
     applyStatesToMatrixDirectly (center.stickers[stickerIndex]); 
    } 

    for (var childIndex in center.children) { 
     center.children[childIndex].model.rotateOnAxis (axis, distance); 
     applyStatesToMatrixDirectly (center.children[childIndex].model); 

     for (var childStickerIndex in center.children[childIndex].stickers) { 
      center.children[childIndex].stickers[childStickerIndex].rotateOnAxis (axis, distance); 
      applyStatesToMatrixDirectly (center.children[childIndex].stickers[childStickerIndex]); 
     } 
    } 
} 

function applyStatesToMatrixDirectly (model) { 
    model.updateMatrix(); 
    model.geometry.applyMatrix(model.matrix); 
    model.position.set(0, 0, 0); 
    model.rotation.set(0, 0, 0); 
    model.scale.set(1, 1, 1) 
    model.updateMatrix(); 
} 

的想法是,applyStatesToMatrixDirectly()的函數直接將旋轉傳遞給模型矩陣,然後重置所有的旋轉數據(以及作爲一切)。這允許模型「忘記」它已經旋轉,允許新的rotateOnAxis工作。