Найти вращение и перекос преобразования матрицы
У меня есть следующая матрица преобразования в 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 ответа
Мне нужна была та же функциональность, и сегодня я получил этот код, который работает очень хорошо.
Я черпал вдохновение здесь: 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 перед разложением являются значениями перевода. Вы можете извлечь их напрямую.
Нашли определение ваших матриц здесь. У нас есть матрица преобразования 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 в виде чистой матрицы вращения. Затем вы можете использовать тригонометрию, чтобы узнать один угол поворота, например, так
rotation = atan2(Q21, Q11)
Перекос и перевод будут найдены в матрице R.
/ sx k tx \
R = | 0 sy ty |
\ 0 0 1 /
Где sx и sy - масштаб, а k - сдвиг. Я не знаю, как этот сдвиг связан с перекосом CSS.
Я не знаю, доступна ли QR-декомпозиция в javascript, но это должно быть достаточно легко реализовать, используя Числовые Рецепты в качестве ссылки.
Не полный ответ, чтобы получить параметры для создания нового объекта матрицы, но он должен направить вас в правильном направлении!