Подтвердить что ты не робот

Вращение матрицы 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 для вычисления всех матриц.

Итак, пожалуйста, помогите мне в том, как использовать мой новый вектор для правильного вращения матрицы.

4b9b3361

Ответ 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 как новое преобразование.