Найти вращение и перекос преобразования матрицы - PullRequest
15 голосов
/ 24 февраля 2011

У меня есть следующая матрица преобразования в 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 ]

18 голосов
/ 20 августа 2015

Мне нужна была та же функциональность, и сегодня я получил этот код, который работает очень хорошо.

Я получил вдохновение здесь: 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 перед разложением являются значениями перевода.Вы можете извлечь их напрямую.

12 голосов
/ 24 февраля 2011

Нашел определение ваших матриц здесь .У нас есть матрица преобразования 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 в форме матрицы вращения pure .Затем вы можете использовать тригонометрию, чтобы определить единственный угол поворота, например, так:

rotation = atan2(Q21, Q11)

Перекос и перевод будут найдены в матрице R.

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

Где sx и sy - масштаб, а k - сдвиг .Я не знаю, как этот сдвиг связан с перекосом css.

Я не знаю, доступно ли QR-разложение в javascript, но это должно быть достаточно легко реализовать, используя Числовые рецепты в качестве справки.

Не полный ответ, чтобы получить параметры для создания нового объекта матрицы, но он должен направить вас в правильном направлении!

...