2012-07-02 2 views
3

Я немного запутался в том, как именно метод postScale вычисляет значения матрицы. Вот код:Результат метода Matrix.postScale (int, int)

Matrix m1 = new Matrix(); 
float[] values = { 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f, 9f }; 
m1.setValues(values); 
Matrix m2 = new Matrix(m1); 

m1.preScale(2f, 3f); //result: 2, 6, 3, 8, 15, 6, 14, 24, 9 
m2.postScale(2f, 3f); //result: 1, 2, 3, 6, 7.5, 9, 3.5, 4, 4.5 

Документация говорит, что результат Prescale является (Matrix * шкала) и результат postScale есть (шкала * Матрица). Но результаты меняются, если я вычисляю матрицы вручную.

размножаются справа:

1 2 3 | 2 0 0 2 6 3 
4 5 6 | 0 3 0 = 8 15 6 
7 8 9 | 0 0 1 14 24 9 

умножения слева направо:

2 0 0 | 1 2 3 2 4 6 
0 3 0 | 4 5 6 = 12 15 18 
0 0 1 | 7 8 9 7 8 9 

... левое умножение (postScale) возвращает другой результат, чем я ожидал.

Я даже посмотрел на встроенную реализацию (Matrix_Delegate.java). Но я не знаю, где проблема. Есть что-то, что мне не хватает?

ответ

2

После того, как setConcat (в android/external/skia/src/core/SkMatrix.cpp), умножает две матрицы, из которых по крайней мере одна является перспективной матрицей, она вызывает метод, называемый normalize_perspective. Если последняя ячейка матрицы (нижний правый угол, мат [2] [2], если нулевой индекс, мат [8] в этом представлении) больше 1, он делит каждое число в матрице на два. Это, безусловно, описывает то, что мы видим здесь.

Но как наша дружественная матрица воспринимается как перспективная матрица? Что ж. Когда мы делаем setValues ​​(), тип устанавливается как Неизвестный. Когда setConcat вызывает getType, он видит «неизвестно» и решает что-то сделать с этим. Он вызывает computeTypeMask. computeTypeMask смотрит на третий столбец, видит, что это не [0 0 1], и удаляет метку Perspective по типу матрицы. Это происходит с вашим м2.

Но почему все это только проблема для postScale? preScale (если библиотека Skia не скомпилирована в режиме фиксированной точки) делает сам масштабирование, поэтому он никогда не попадает в setConcat, чтобы нанести удар по этим каменистым отмелям.

Почему нормализуется хорошая идея? Проклятый, если я знаю. Вероятно, это связано с ожидаемыми 2d графическими приложениями для этих конкретных процедур.

Что вы можете сделать со всем этим? Если вы ориентируетесь на уровень API 11 или выше, то Matrix3f от renderscript, вероятно, ваш друг. Если нет, извините, D-Fox, ваша матричная реализация находится в другом замке.

+0

(Если вы очень плохой человек, вы можете разделить все значения в вашей матрице на значения [8], выполнить postScale, а затем умножить все значения в вашей матрице на значения [8]. Это работает на стоимость многочисленных смертей котенка) – Iain

+0

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

Смежные вопросы