2011-01-14 123 views
6

我用Papervison3D创建了这个Rubiks多维数据集。有了一些资源,我创建了一个27个微型立方体(3 * 3 * 3 = 27)的立方体。鼠标移动Rubiks立方体已经完成。 (我不旋转相机。)四元数多维数据集旋转动画

Rubiks Cube的所有行为已经存在。但我在最后阶段有点卡住了。

当我玩它像我会做一个正常的Rubiks立方体它工作正常,除了我知道默认的欧拉旋转值不再可靠了一段时间后。我需要的是将Rubiks立方体旋转到选定的一侧,然后将Rubiks立方体旋转到Z轴上,使微型立方体面朝上。我更喜欢用TweenMax制作动画,但由于我需要四元数旋转,所以我真的陷入困境。

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

我需要的是将其更改为四元数值并将Rubiks立方体旋转为新的四元数值。之后,它必须旋转Rubiks立方体在其z轴上面朝上面向选定的微型立方体。

这是拖动/旋转Rubiks魔方

当我使用的代码
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; 
} 
+2

我试图按照你的问题,但做起来很难。你能否试着更清楚你需要什么?附:我不是Flash程序员。 “默认的欧拉旋转值在一段时间后不可靠”是什么意思?我怀疑你想保留rubic的cube的内部*逻辑*表示而不是它们的物理位置。 – 2011-01-15 17:34:47

回答

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; 
    } 
}