2011-01-14 126 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; 
    } 
}