轮换后的旋转不按我的预期行事

时间:2016-02-27 23:11:28

标签: three.js

我有一个像rubiks-cube一样的谜题我试图使用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 ] );
}

有趣的是,为了让Blue-Orange-Yellow角正确旋转,我需要围绕BO矢量和OW矢量之间的差异进行旋转。

也就是说:

  • 蓝橙轴是标准化的矢量:(0,1,1)
  • 橙 - 白轴是标准化的矢量:(1,0,1)
  • 第一次旋转完成后,如果我尝试旋转BOY 在(1,0,1)的法线周围转角,我得到了显示的行为 图片。
  • 但是,如果我尝试旋转它(0,1,1) - (1, 0,1),即(-1,1,0),我得到了所需的行为。

我不明白发生了什么。你能帮助我更新我的旋转功能,这样我就可以得到我想要的行为,而不必保留一个片段经历的过去旋转的长列表吗?

我怀疑在我第一次轮换之后,我需要把这个部分告诉&#34;零&#34;它的旋转状态没有引起任何动作,但我不太清楚如何做到这一点,或者它是否是正确的方法。

你可以在这里玩这个东西:http://joshuad.net/clover-cube/so-question/

谢谢!

1 个答案:

答案 0 :(得分:0)

我通过将旋转方法更改为:

来修复它
public E remove(int index)

这个想法是函数applyStatesToMatrixDirectly()将旋转直接应用于模型矩阵,然后重置所有旋转数据(以及其他所有内容)。这允许模型“忘记”它已被旋转,允许新的rotateOnAxis工作。