Вращение матрицы CSS3
У меня есть 3D-куб CSS, который я пытаюсь повернуть влево/вправо/вверх/вниз прямо, как кажется пользователю. Если я использую функции css rotation
, тогда я поворачиваю ось, а не куб.
В Интернете есть много статей о вычислении вращения матрицы X, Y, Z, но я потратил несколько дней, пытаясь установить эту вещь, и ни одна из этих данных не помогает мне.
Работа вокруг моей проблемы будет WebKitCSSMatrix
объектом, который имеет свои собственные функции вращения, которые работают как магические. Пример на Fiddle: http://jsfiddle.net/joecritch/tZBDW/. Но опять же, это зависит только от Webkit, но мне нужно быть кроссбразом здесь.
Теперь на пути успеха есть 3 шага:
1) Мне нужно получить текущую матрицу, задать вектор направленности (1,0,0 для вверх/вниз и 0,1,0 для левого/правого вращения) и установить угол. СДЕЛАНО.
2) Мне нужно вычислить новый вектор вращения на основе текущей матрицы. СДЕЛАНО.
3) Мне нужно повернуть мою текущую матрицу новым вектором и углом. ПРОБЛЕМА.
var newMArray = deMatrix(".cube");//getting current matrix from CSS
var v = [vecX, vecY, vecZ, 0];//current vector (1,0,0) or (0,1,0)
var newV = newMVector(newMArray, v);//calculating new vector for current matrix
//getting the angle for each axis based on new vector
angleX = newV[0]*angle;
angleY = newV[1]*angle;
angleZ = newV[2]*angle;
this.rotateX -= angleX;
this.rotateY -= angleY;
this.rotateZ -= angleZ;
//calculating the rotation matrix
var rotationXMatrix, rotationYMatrix, rotationZMatrix, s, transformationMatrix;
rotationXMatrix = $M([[1, 0, 0, 0], [0, Math.cos(this.rotateX * deg2rad), Math.sin(-this.rotateX * deg2rad), 0], [0, Math.sin(this.rotateX * deg2rad), Math.cos(this.rotateX * deg2rad), 0], [0, 0, 0, 1]]);
rotationYMatrix = $M([[Math.cos(this.rotateY * deg2rad), 0, Math.sin(this.rotateY * deg2rad), 0], [0, 1, 0, 0], [Math.sin(-this.rotateY * deg2rad), 0, Math.cos(this.rotateY * deg2rad), 0], [0, 0, 0, 1]]);
rotationZMatrix = $M([[Math.cos(this.rotateZ * deg2rad), Math.sin(-this.rotateZ * deg2rad), 0, 0], [Math.sin(this.rotateZ * deg2rad), Math.cos(this.rotateZ * deg2rad), 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]);
transformationMatrix = rotationXMatrix.x(rotationYMatrix).x(rotationZMatrix);//getting all axis rotation into one matrix
Чем я устанавливаю новую матрицу преобразования в свой CSS-куб. Проблема в том, что она не вращается так, как должна. Теперь я использую плагин Sylvester
для вычисления всех матриц.
Итак, пожалуйста, помогите мне в том, как использовать мой новый вектор для правильного вращения матрицы.
Ответы
Ответ 1
Сильвестр может генерировать матрицы вращения. Глядя на пример скрипки - функция webkit, которая, похоже, выполняет поворот:
// Rotate the Matrix around the transformed vector
var newMatrix = m.rotateAxisAngle(vector.x, vector.y, vector.z, angle);
Похоже, что это больше по строкам функции Matrix.Rotation(angle [, axis])
, я полагаю, что вы предоставили бы axis
как объект Vector Сильвестра, а не аргументы webkit x, y, z - http://sylvester.jcoglan.com/api/matrix.html#rotation
Умножение матриц x, y, z не работает слишком хорошо, потому что дополнительные преобразования будут применены в новом контексте. Я просто попал в эту ловушку с этой страницей js/canvas: http://benjaminbenben.com/projects/twittny_test/
Ответ 2
Мне очень тяжело следовать вашему коду. Но если я правильно понимаю, вы действительно идете вокруг основной проблемы назад.
Ваша начальная точка - это объект с матричным преобразованием. Вы хотите изменить это преобразование. На данный момент очень заманчиво просто попробовать что-то и посмотреть, какие палки. Не обижайтесь, но это то, что ваш код выглядит так, как будто он делает. Вам действительно нужно понять, как работают матрицы. Есть много хороших уроков. (первый хит google: http://chortle.ccsu.edu/vectorlessons/vectorindex.html). В долгосрочной перспективе потребуется много времени.
Основная проблема, с которой вы сталкиваетесь, заключается в том, что матричное умножение не является коммутативным. A * B!= B * A для матриц. В зависимости от того, какую матрицу вы устанавливаете, она включает в себя множество преобразований, в которых значение порядка: (A) Перемещение объекта к нему из источника (B) Поверните объект вокруг него (C) Переместите объект в положение в мире (D) Переместите объект туда, где камера находится в начале координат (E). Поверните камеру вокруг камеры. Матрица, которую вы видите, просто A * B * C * D * E. Теперь в зависимости от того, что вы хотите сделать, вам лучше иметь хороший план. В большинстве случаев вы либо хотите повернуть объект, либо камеру, и можете просто размножаться либо с левой, либо с правой стороны. Ваш код выглядит немного похоже на то, что вы умножаетесь не на ту сторону и пытаетесь перепрыгнуть через обручи, чтобы компенсировать это, что несколько работает, потому что многие матрицы являются тождественными.
Итак, еще более практично: получите свою матрицу куба, внесите независимую от него матрицу вращения (no -angle!) и установите обратное вращение * cubematrix как новое преобразование.