Find the Rotation and Skew of a Matrix transformation

谁说胖子不能爱 提交于 2019-11-30 06:58:36

问题


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)"

And i can find the rotation using this...

// 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

Similarly for skew if...

// 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] 

However as soon as i use both skew and rotation everything goes weird not least because the formula for rotation is identical to that of skew... so the formulas can't be right.

How do i determine both rotation & skew where both attributes have been applied and all i know is the Matrix Transform.

Also scale messed up my skew values, which i dont think it should.


回答1:


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.




回答2:


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!



来源:https://stackoverflow.com/questions/5107134/find-the-rotation-and-skew-of-a-matrix-transformation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!