2013-11-01 60 views
1

我有以下JSFiddle http://jsfiddle.net/3vf9J/這突出了我的問題。CSS matrix3d計算不正確,但爲什麼?

我跟着就如何使一個函數來CSS結合導向轉變成一個Matrix3D這樣我就可以比蘋果每次一個多。

不幸的是我無法正常工作。圍繞一個軸簡單旋轉180度,最終看起來更像135度,所以我清楚地發現一些數學錯誤。

能理解矩陣的人能幫助我嗎?

我的功能看起來是這樣的:

var generateRotationMatrix = function(x, y, z, tx, ty, tz) { 
    var a = x; 
    var b = y; 
    var c = z; 

    var rotationXMatrix = $M([ 
     [1,0,0,0], 
     [0,Math.cos(a), Math.sin(-a), 0], 
     [0,Math.sin(a), Math.cos(a), 0], 
     [0,0,0,1] 
    ]); 

    var rotationYMatrix = $M([ 
     [Math.cos(b), 0, Math.sin(b),0], 
     [0,1,0,0], 
     [Math.sin(-b), 0, Math.cos(b), 0], 
     [0,0,0,1] 
    ]); 

    var rotationZMatrix = $M([ 
     [Math.cos(c), Math.sin(-c), 0, 0], 
     [Math.sin(c), Math.cos(c), 0, 0], 
     [0,0,1,0], 
     [0,0,0,1] 
    ]); 

    var translationMatrix = $M([ 
       [1,0,0,0], 
       [0,1,0,0], 
       [0,0,1,0], 
       [tx,ty,tz,1] 
        ]); 
    var tM = rotationXMatrix 
      .x(rotationYMatrix) 
      .x(rotationZMatrix) 
     .x(translationMatrix); 

    var s = "matrix3d(" 
    s += tM.e(1,1).toFixed(10) + "," + tM.e(1,2).toFixed(10) + "," + tM.e(1,3).toFixed(10) + "," + tM.e(1,4).toFixed(10) + "," 
    s += tM.e(2,1).toFixed(10) + "," + tM.e(2,2).toFixed(10) + "," + tM.e(2,3).toFixed(10) + "," + tM.e(2,4).toFixed(10) + "," 
    s += tM.e(3,1).toFixed(10) + "," + tM.e(3,2).toFixed(10) + "," + tM.e(3,3).toFixed(10) + "," + tM.e(3,4).toFixed(10) + "," 
    s += tM.e(4,1).toFixed(10) + "," + tM.e(4,2).toFixed(10) + "," + tM.e(4,3).toFixed(10) + "," + tM.e(4,4).toFixed(10) 
    s += ")"; 
    return s; 
} 

請注意我用Sylvester做我的矩陣數學(倍增)

回答

1

更新(2014年4月22日)通過thisiate - 原作者

由於我正在做類似的事情,所以這個問題出現在我的腦海裏,所以在仔細觀察它的時候,我注意到了這個錯誤,並發現了它的原因。這裏是一個簡短的解釋。

平移矩陣是錯誤的:

var translationMatrix = $M([ 
      [1,0,0,0], 
      [0,1,0,0], 
      [0,0,1,0], 
      [tx,ty,tz,1] 
       ]); 

需求被改寫:

var translationMatrix = $M([ 
      [1,0,0,tx], 
      [0,1,0,ty], 
      [0,0,1,tz], 
      [0,0,0,1] 
       ]); 

這個小錯誤解釋了爲什麼你看到一個奇怪的結果。矩陣乘法中某些東西將乘以零的3個位置現在乘以變換變量,從而計算出不同的角度。而且,任何變換都不會被應用,因爲0基本上是常量。此外,tz的位置最初影響處理透視的矩陣部分。

我相信這應該解決矩陣部分的任何問題。我原來的回答是基於rotate3d被限制在360度(0-359)的事實。由於正弦波和餘弦波的週期,插值爲模數360值時,不能通過360或-360。例如rotateX valueX1 rotateY valueY1rotateX valueX2 rotateY valueY2之間的變換實際上會直接內插並在CSS引擎內部使用該結果(所有這些變換將由視頻處理器(如果可用的話而不是CPU)進行硬件加速)並且將比計算矩陣變換更快。

原來的答覆如下:

馬特,如果你想單獨申請多個轉換,並有一個簡單的方法來改變的變換(說rotateX),see this answer I gave for a different solution每個單獨的元素。

你不需要使用matrix3d來得到你想要的。瀏覽器將處理結果轉換(如果可用,使用圖形處理器)。意識到旋轉變換的順序寫入影響最終輸出隨着參考系的變化而變化很重要。例如,當您執行rotateY(180deg)時,現在引用框架會將X軸和Z軸更改爲它們的對立面,因爲您現在正盯着元素的背面(負X值位於右側) Y軸向左爲正,同樣,Z軸負值現在比0更接近你,正Z軸值進入屏幕)。

爲了便於弄清楚多次旋轉的元素會發生什麼,取一張卡片或類似的紙張,繪製X軸和Y軸,然後將牙籤穿過原點,使其更多地穿過請注意,在瀏覽器中,Y向下,而不是向上。現在從第一次旋轉開始,用紙做3d。重複所有的旋轉,然後做任何翻譯,然後縮放(你將不得不想象這個),等等。