6

我用 Papervison3D 创建了这个魔方。使用一些资源,我创建了一个内部有 27 个小立方体的立方体 (3*3*3 = 27)。在鼠标移动时旋转魔方已经完成。(我不旋转相机。)

魔方的所有行为都已经存在。但我有点卡在最后阶段。

当我像使用普通魔方一样使用它时,它工作正常,此外我知道默认的欧拉旋转值在一段时间后不再可靠。我需要将魔方旋转到选定的一侧,然后在 z 轴上旋转魔方,使迷你魔方面朝上。我更喜欢使用 TweenMax 对其进行动画处理,但我真的被困住了,因为我需要四元数旋转。

我知道魔方本身的选定面。我知道魔方的欧拉旋转使用Matrix3D.matrix2euler(_rubiksCube.transform);我需要的是将它旋转到选定的面,例如当当前旋转是x: -20, y: 35, z: 10并且我选择它必须旋转到的魔方的背面时x:0, y: 180, z: 0

我需要将其更改为四元数值并将魔方旋转到新的四元数值。之后,它必须在它的 z 轴上旋转魔方,使选定的小魔方面朝上。

这是我在拖动/旋转魔方时使用的代码

private function onMouseMove( e : MouseEvent) : void {
    var m : Matrix3D;
    m = Matrix3D.rotationY( (mouseX - _mouseDownPoint.x) / 120 );
    m = Matrix3D.multiply( m, Matrix3D.rotationX( -(mouseY - _mouseDownPoint.y) / 120 ));
    _rubiksCube.transform = Matrix3D.multiply( m, _rubiksCube.transform );
    _mouseDownPoint.x = mouseX;
    _mouseDownPoint.y = mouseY;
}
4

1 回答 1

4

四元数绝对是要走的路。自从我使用 PV3D 以来已经有一段时间了,但它是这样的:

  1. 将欧拉角存储在单独的变量中(例如,u、v、w)。在计算中累积这些变量。
  2. 使用 Quaternion.createFromEuler() 创建一个四元数;
  3. 使用 quaternion.matrix 进行变换

例如:

var yRotation:Number = 0;
var xRotation:Number = 0;

function mouseHandler(e:MouseEvent):void {
    yRotation += (mouseX - _mouseDownPoint.x) / 120;
    xRotation += -(mouseY - _mouseDownPoint.y) / 120);

    var q:Quaternion = Quaternion.createFromEuler(xRotation, yRotation, zRotation, true);  
    _rubiksCube.transform = q.matrix;
    _mouseDownPoint.x = mouseX;
    _mouseDownPoint.y = mouseY;
}

更新:啊,我又读了你的问题。听起来您想从当前方向平滑地插值到新方向。以前对我有用的是:

  1. 获取当前的欧拉位置并使用 Quaternion.createFromEuler() 转换为四元数。
  2. 获取目标四元数。
  3. 使用 quaternion.slerp() 随时间从源四元数插入到目标。

例如:

function clickHandler(e:MouseEvent):void {
    qSource = qCurrent;
    qTarget = quaternion.createFromEuler(....);
    t = getTimer();
}

function frameHandler(e:Event):void {
    if (isAnimating) {
        tDelta = (getTimer() - t) / 10000; // 10000 = 10 seconds
        qCurrent = slerp(qSource, qTarget, tDelta);
        _rubiksCube.transform = qCurrent.matrix;
    }
}
于 2011-07-30T22:26:04.223 回答