找到矩阵变换的旋转和偏斜

时间:2011-02-24 16:02:42

标签: javascript matrix qr-decomposition

我在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] 

然而,只要我同时使用倾斜和旋转,一切都变得奇怪,尤其是因为旋转公式与倾斜公式相同...所以公式不能正确。

我如何确定旋转和放大?两个属性都已应用的倾斜,我所知道的就是矩阵变换。

同时缩放也搞砸了我的偏斜值,我认为不应该这样做。

2 个答案:

答案 0 :(得分:18)

我需要相同的功能,今天我最终得到了非常好的代码。

我从这里获取灵感: https://www.youtube.com/watch?v=51MRHjKSbtk 并且从answer below,没有提示 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中的最后两个项是翻译值。您可以直接提取它们。

答案 1 :(得分:12)

找到矩阵here的定义。我们有转换矩阵 T

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

对于以下表达式

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

为了检索用于构建该矩阵的参数,我们需要首先找到矩阵 T 的分解。假设在旋转后应用了倾斜,我们可以找到QR-decomposition

QR = T

旋转将以旋转矩阵的形式在 Q 矩阵内找到。然后,您可以使用三角学来找出单个旋转角度,例如像

rotation = atan2(Q21, Q11)

偏斜和平移将在R矩阵中找到。

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

其中 sx sy 是比例, k 表示剪切。我不知道这种剪切与css-skew有什么关系。

我不知道在javascript中是否可以使用QR分解,但使用Numerical Recipes作为参考应该很容易实现。

获取参数以创建新的矩阵对象不是一个完整的答案,但应该让你朝正确的方向走!