17

CSSに次の変換マトリックスがあります

// rotate the element 60deg
element.style.transform = "matrix(0.5,0.866025,-0.866025,0.5,0,0)"

そして、これを使用して回転を見つけることができます...

// where a = [0.710138,0.502055,-0.57735,1,0,0]
var rotation = ((180/Math.PI) * Math.atan2( ((0*a[2])+(1*a[3])),((0*a[0])-(1*a[1]))) - 90
console.log(rotation); // ~60

スキューについても同様に...

// skew(30deg,-50deg) 
element.style.transform = "matrix(1,-1.19175,0.57735,1,0,0)"

var skewY = ((180/Math.PI) * Math.atan2( ((0*a[2])+(1*a[3])),((0*a[0])-(1*a[1]))) - 90;
var skewX = (180/Math.PI) * Math.atan2( ((1*a[2])+(0*a[3])),((1*a[0])-(0*a[1])));

console.log([skewX,skewY]); // ~= [30,-50] 

ただし、スキューと回転の両方を使用するとすぐに、特に回転の式がスキューの式と同じであるため、すべてが奇妙になります...したがって、式は正しくありません。

両方の属性が適用されている回転と傾斜の両方を決定するにはどうすればよいですか。私が知っているのはマトリックス変換だけです。

また、スケールによってスキュー値が台無しになりましたが、これはすべきではないと思います。

4

2 に答える 2

23

同じ機能が必要でしたが、今日は非常にうまく機能するこのコードになりました。

私はここからインスピレーションを得ました: https://www.youtube.com/watch?v=51MRHjKSbtk以下の回答から、 QR 分解のヒントがなければ、私は決してそれを見つけることができませんでした

私は 2x2 のケースに取り組んでいましたが、翻訳も含めるために 2x3 に拡張しようとしています。しかし、それは簡単なはずです

var a = [a, b, c, d, e, f];
var qrDecompone = function(a) {
  var angle = Math.atan2(a[1], a[0]),
      denom = Math.pow(a[0], 2) + Math.pow(a[1], 2),
      scaleX = Math.sqrt(denom),
      scaleY = (a[0] * a[3] - a[2] * a[1]) / scaleX,
      skewX = Math.atan2(a[0] * a[2] + a[1] * a[3], denom);
  return {
    angle: angle / (Math.PI / 180),  // this is rotation angle in degrees
    scaleX: scaleX,                  // scaleX factor  
    scaleY: scaleY,                  // scaleY factor
    skewX: skewX / (Math.PI / 180),  // skewX angle degrees
    skewY: 0,                        // skewY angle degrees
    translateX: a[4],                // translation point  x
    translateY: a[5]                 // translation point  y
  };
};

分解前の transformMatrix の最後の 2 つの項目は、変換値のようです。それらを直接抽出できます。

于 2015-08-20T18:28:02.543 に答える
14

ここで行列の定義を見つけました。変換行列T

    / a b tx \
T = | c d ty |
    \ 0 0 1  /

次の式の場合

element.style.transform = "matrix(a,b,c,d,tx,ty)"

この行列を構築するために使用されるパラメータを取得するには、まず行列Tの分解を見つける必要があります。回転後にスキューが適用されると仮定すると、 QR 分解を見つけることができます。

QR = T

回転は、純粋な回転行列の形式でQ行列内に見つかります。次に、三角法を使用して、たとえば次のように単一の回転角度を見つけることができます

rotation = atan2(Q21, Q11)

スキューと平行移動は、R マトリックスで検出されます。

    / sx   k  tx \
R = |  0  sy  ty |
    \  0   0   1 /

ここで、 sxsyはスケールで、kはせん断を表します。このせん断が css-skew とどのように関係しているかはわかりません。

QR 分解が JavaScript で利用できるかどうかはわかりませんが、参考としてNumerical Recipesを使用して実装するのは簡単なはずです。

パラメータを取得して新しい行列オブジェクトを作成するための完全な答えではありませんが、正しい方向に進むはずです!

于 2011-02-24T17:53:25.823 に答える