2015-07-15 3 views
1

Использование библиотеки android.graphics.Matrix:вращения поступательной составляющей матрицы

Matrix foo = new Matrix(); 

foo.setTranslate(10.0f, 0.0f); 
Log.d("MatrixTest", foo.toString()); 

foo.postRotate(30.0f, 0.0f, 0.0f); 
Log.d("MatrixTest", foo.toString()); 

я получаю следующий вывод:

foo = {[1.0, 0.0, 10.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]} 
foo = {[0.8660254, -0.5, 8.660254][0.5, 0.8660254, 5.0][0.0, 0.0, 1.0]} 

Какой именно то, что я хотел бы ожидать.

Теперь было бы полезно, чтобы мое приложение также запускалось на рабочем столе, поэтому я переношу на libgdx.

Использование библиотеки com.badlogic.gdx.math.Matrix3:

Matrix3 bar = new Matrix3(); 

bar.translate(10.0f, 0.0f); 
System.out.println(bar.toString()); 

bar.rotate(30.0f); 
System.out.println(bar.toString()); 

я получаем следующий результат:

bar = [1.0|0.0|10.0] [0.0|1.0|0.0] [0.0|0.0|1.0] 
bar = [0.8660254|-0.5|10.0] [0.5|0.8660254|0.0] [0.0|0.0|1.0] 

В этом случае, перевод компонент X не вращается ,

Это правильное поведение? API для метода android postRotate() и метода rotag() libgdx описывает их как функции после поворота.

Я получаю похожие результаты для libgdx Matrix4, и это то, что я бы действительно хотел использовать.

Может ли кто-нибудь предложить хороший способ воспроизвести результаты, полученные в андроидной библиотеке, используя libgdx Matrix3 или 4?

+0

Я думаю, что замена операции должны сделай то, что ищешь. Поэтому сначала поверните, а затем переведите. Если это так, я объясню немного подробнее в ответе. –

+0

Вы, конечно, правы. Я понимаю, что матричное умножение не является коммутативным. Но так как оба API-интерфейса рекламируют себя как postMultiply, неудивительно, что они не дают одинакового результата! – Itch

+0

Ну, второй, похоже, использует стандартные операции, так что либо документация неверна, либо она интерпретируется с ошибкой. –

ответ

0

Просто, чтобы получить вещи ясно ...

Это наименее неоднозначное, если вы просто придерживаться матричного умножения, то пытается использовать удобные методы, чтобы использовать операции на самих матрицах.

В большинстве случаев при выполнении операции над матрицей, такой как перевод, что произойдет, будет создана матрица перевода, а исходная матрица будет умножаться на новую матрицу как originalMatrix*translationMatrix. Это то, что происходит во втором примере. В вашем первом примере есть префикс «post», который, как представляется, выполняет операцию invers translationMatrix*originalMatrix.

Я могу понять, что это «сообщение» может быть полезно, и для тех, кто не очень хорошо разбирается в матричных операциях, он может быть более естественным в использовании. То, что я не могу понять, это «postMultiply». Это не так, как это работает вообще, это не то, как используется матричное умножение, и только смущает большинство разработчиков. Не только в процессе обучения, но даже если позже кто-то прочитает этот код. Конечно, это работает, но для меня это было бы то же самое, как писать что-то вроде этого:

Print первые N целые значения:

for(int i=N; i>0; --i) 
    { 
     int printValue = N-i+1; 
     // print the printValue 
    } 

уверен, что это работает, но для меня это совершенно нечитаемым.

Если в любом случае у вас возникли проблемы с представлением матричного умножения, вы должны думать об этом так, как если бы вы смотрели на него от первого лица. Например, перевести на ось X будет означать шаг вперед, Y слева и Z вверх. Вращения тогда только вокруг вашего центра и никогда не будут влиять на ваше положение.

Итак, в первом примере вы сначала повернете влево влево на 30 градусов, и теперь вы смотрите в сторону (0.8660254, 0.5).Затем вы переводите на 10 по оси X, что означает шаг вперед на 10 пунктов, и ваше положение становится (0.8660254, 0.5)*10.0, поэтому вы попадаете в (8.660254, 5.0), обращаясь к (8.660254 + 0.8660254, 5.0 + 0.5).

Во втором примере вы сначала переводите на 10 точек вдоль оси X, что означает, что нужно идти вперед на 10 пунктов, заканчивающихся на (10, 0), все еще находящихся в одном направлении, а затем вы поворачиваете на 30 градусов влево и просто оказываетесь в том же месте на (10.0, .0), обращенной к (10.0+0.8660254, .0+.5).

Как вы теперь можете видеть из результатов, вы получаете столбцы в своей матрице (а не строки в вашем случае), определяете векторы матрицы. Таким образом, просто из этих векторов вы можете понять, к какому пути относится объект, и где он находится в центре. Вы также можете просто построить матрицу из этих векторов. Если вы хотите, чтобы создать матрицу для объекта, который находится в положении P и сталкивается в направлении D то матрица:

D.x, D.y, .0 
-D.y, D.x, .0 
P.x, P.y, 1.0 

В вашем случае транспонированной

D.x, -D.y, P.x 
D.y, D.x, P.y 
.0, .0, 1.0 
Смежные вопросы