Javascript 求矩阵变换的旋转和倾斜

Javascript 求矩阵变换的旋转和倾斜,javascript,matrix,qr-decomposition,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[

我有以下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] 
然而,当我同时使用倾斜和旋转时,一切都变得很奇怪,尤其是因为旋转的公式和倾斜的公式是相同的。。。所以这些公式不可能是正确的

我如何确定旋转和倾斜,这两个属性都已应用,我只知道矩阵变换


此外,scale还弄乱了我的倾斜值,我认为这是不应该的。

找到了矩阵的定义。我们有变换矩阵T

    / a b tx \
T = | c d ty |
    \ 0 0 1  /
对于下面的表达式

element.style.transform = "matrix(a,b,c,d,tx,ty)"
为了检索用于建立该矩阵的参数,我们需要首先找到矩阵的分解T。假设旋转后应用了倾斜,我们可以找到:

QR=T

    / a b tx \
T = | c d ty |
    \ 0 0 1  /
旋转将以纯旋转矩阵的形式在Q矩阵中找到。然后可以使用三角学来确定单个旋转角度,例如

rotation = atan2(Q21, Q11)
倾斜和平移将在R矩阵中找到

    / sx   k  tx \
R = |  0  sy  ty |
    \  0   0   1 /
式中,sx和sy为刻度,k为剪力。我不知道这种剪切与css倾斜有什么关系

我不知道QR分解在javascript中是否可用,但使用as引用应该很容易实现


这不是一个完整的答案来获取参数来创建一个新的矩阵对象,但应该让您朝着正确的方向前进

我需要同样的功能,今天我得到了这段代码,效果非常好

我从这里得到了灵感: 而且,如果没有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中的最后两项似乎是平移值。您可以直接提取它们。

有趣的问题。每个矩阵中有六个元素。这是一个3x3矩阵,最后一行隐式设置为(0,0,1)?是的,javascript(2dcanvas relataed)中使用的转换矩阵将最新一行隐式设置为[0,0,1]。我对答案进行了进一步润色,效果非常好,感谢您的回复。我把这个项目搁置了一会儿。等我有时间,我会继续你刚才说的。但事实上这是我学过的非常简单的向量矩阵。我说的很简单。。。我还没算出来。:)感谢我对我的答案进行投票:)其实没那么简单,但应该绝对可行。多亏了你的提示,我可以在我的答案下面找到解决方案,并用完整的代码对矩阵进行反编译。太棒了!干得好:)应该是公认的答案@Drewdo你有错误的角度吗?在什么情况下?我经常使用这个函数,但没有得到任何结果。对理解感兴趣。我正在使用它处理从Flash导出的SVG,当我使用atan2(c,a)时,它产生了不正确的旋转值,而atan2(b,a)对我有效。问你一个问题,安德里亚:第一行[a,c,b…]上矩阵的顺序是正确的,还是打字错误?我看到的所有其他参考资料,包括下面维斯蒂奇的答案,都按字母顺序列出了各个部分。我还没有测试过这个问题,但是如果切换到[a,b,c…],而不做任何其他代码更改,会产生一个有效的歪斜,那么这个错别字可以解释我遇到的问题。@ivanreese我很确定这是一个错别字,示例应该是
var a=[a,b,c,d,e,f]。肯定是打字错误。不管怎样,这个函数确实改变了我在fabric.js中可以解决的问题,我对此感到非常高兴。