【问题标题】:Rotation after a Rotation not acting how I Expect轮换后的轮换不符合我的预期
【发布时间】:2016-06-11 03:21:27
【问题描述】:

我有一个类似魔方的谜题,我正在尝试使用 Three.js 在 webgl 中建模:

双色中心中的每一个都可以旋转。当它们旋转时,它们会带动周围的所有碎片一起旋转。例如,如果我们旋转橙蓝色中心,会发生以下情况:

当你完成一个轮换后,一切都排好了:

但是,现在当我尝试旋转橙白中心时,在第一次旋转后它从橙蓝中心继承的两个部分出现了奇怪的行为:

我希望它们像其他部分一样旋转,但它们的旋转方式不同。

我正在使用 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, 1),即 (-1, 1, 0),我得到了想要的行为。

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

我怀疑在我进行第一次旋转后,我需要告诉部件将其旋转状态“归零”而不引起任何运动,但我不太确定如何做到这一点,或者这是否是正确的方法。

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

谢谢!

【问题讨论】:

    标签: three.js


    【解决方案1】:

    我通过将我的旋转方法更改为这个来修复它:

    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 工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-22
      • 2011-03-17
      • 1970-01-01
      • 2010-12-24
      • 2016-07-07
      • 2013-05-09
      • 1970-01-01
      相关资源
      最近更新 更多