Find the Rotation and Skew of a Matrix transformation

后端 未结 2 1786
温柔的废话
温柔的废话 2020-12-14 19:29

I have the the following Transform Matrix in CSS

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


        
相关标签:
2条回答
  • 2020-12-14 20:09

    Found the definition of your matrices here. We have the transformation matrix T

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

    For the following expression

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

    In order to retrive the parameters used to build up this matrix we need to first find a decomposition of the matrix T. Assuming the skew is applied after the rotation we can find the QR-decomposition:

    QR = T

    The rotation will be found inside the Q matrix in the form of a pure rotation matrix. You can then use trigonometry to find out the single rotation angle, for example like so

    rotation = atan2(Q21, Q11)
    

    The skew and translation will be found in the R matrix.

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

    Where sx and sy is the scale and k represents the shear. I dont know how this shear relates to the css-skew.

    I don't know if the QR decomposition is availble in javascript, but it should be easy enough to implement using the Numerical Recipes as reference.

    Not a complete answer to get the parameters to create a new matrix object, but should set you off in the right direction!

    0 讨论(0)
  • 2020-12-14 20:24

    I needed same functionality and today I ended up with this code that works very good.

    I took inspiration from here: https://www.youtube.com/watch?v=51MRHjKSbtk and from the answer below, without the hint QR decomposition i would never find it out

    I worked on a 2x2 case, i will try to expand to 2x3 to include also translations. But it should be easy

    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
      };
    };
    

    It looks like that the last two items in the transformMatrix, before decomposition, are translation values. You can extract them directly.

    0 讨论(0)
提交回复
热议问题