Почему порядок масштабирования и перевода имеет значение для матрицы модели?

Я играл с созданием матрицы модели и понял, что порядок операций масштабирования и перевода имеет значение. Я использую Qt для своих матриц и использую QMatrix4x4 и использую openGL (но это должно быть независимым от библиотеки и платформы и связано с математикой). Результат уменьшения модели и последующего ее перевода работает только так, как ожидалось, вот так.

    QMatrix4x4 model;
    model.translate(some_vec3d);
    model.scale(some_vec3d);

У меня сложилось впечатление, что математически, поскольку масштаб появляется в первых 3x3 матрицы, а перевод влияет только на последний столбец матрицы (4-й столбец), порядок независим. Когда я смотрю на матрицы, я понимаю, что порядок имеет значение, но не могу понять, почему.


person dev_nut    schedule 06.11.2018    source источник


Ответы (1)


Учитывать:

  • Вершина вашей модели p
  • Масштабная матрица S
  • Матрица переноса T на вектор смещения t

Преобразованная точка, полученная в результате применения:

Translation first: 
     S * T * p = S * (p + t) 
               = S * p + S * t
                         ----- <---
Scaling first:
     T * S * p = S * p + t
                         -     <---

Разница, показанная в матричном умножении:

Translation first:

   | Sx 0  0  0 |   | 1 0 0 Tx |     | Sx 0  0  Sx * Tx |
   | 0  Sy 0  0 | * | 0 1 0 Ty |  =  | 0  Sy 0  Sy * Ty |
   | 0  0  Sz 0 |   | 0 0 1 Tz |     | 0  0  Sz Sz * Tz |
   | 0  0  0  1 |   | 0 0 0 1  |     | 0  0  0     1    |

Scaling first:

   | 1 0 0 Tx |   | Sx 0  0  0 |     | Sx 0  0  Tx |
   | 0 1 0 Ty | * | 0  Sy 0  0 |  =  | 0  Sy 0  Ty |
   | 0 0 1 Tz |   | 0  0  Sz 0 |     | 0  0  Sz Tz |
   | 0 0 0 1  |   | 0  0  0  1 |     | 0  0  0  1  |
person meowgoesthedog    schedule 06.11.2018
comment
Это отличная иллюстрация. Спасибо! И код, который я показываю, работает, потому что он применяет его в столбцах, поэтому операции обратные, в отличие от строк, как вы показали? То есть масштабирование с последующим переводом — вот как это должно работать. - person dev_nut; 06.11.2018
comment
@dev_nut о, хорошо, я не знаю, какое соглашение о матрицах использует Qt, но OpenGL использует мажор строк (с заменой Y и Z). Это зависит от того, как Qt реализует функции перевода и масштабирования; некоторые библиотеки применяют преобразования в обратном порядке. - person meowgoesthedog; 06.11.2018
comment
Даже в glm вам придется выполнять операции в обратном порядке. Я считаю, что openGL имеет приоритет столбцов - opengl.org/archives/resources/ faq/technical/transformations.htm. Но математика везде одинаковая. Вам просто нужно знать порядок, в котором базовая библиотека, которую вы используете, ожидает, что это будет, то есть qt или glm или что-то еще. - person dev_nut; 06.11.2018
comment
@dev_nut извините за ошибку; Суть в том, что матричные уравнения не зависят от соглашений, и они показывают, что если вы примените масштабирование во-вторых, само перемещение также будет масштабировано, тогда как обратное неприменимо. - person meowgoesthedog; 06.11.2018