если я смотрю на заполненную матрицу в моей программе, я вижу компоненты перевода, занимающие 4-й, 8-й и 12-й элементы.
Прежде чем я начну, важно понять: это означает, что ваши матрицы являются основными рядами . Поэтому вы отвечаете на этот вопрос:
Основная WVP-матрица моего столбца успешно используется для преобразования вершин с помощью вызова HLSL: mul (вектор, матрица), что должно привести к тому, что вектор будет рассматриваться как основной-ряд, так как же может работать основная матрица столбца, предоставляемая моей математической библиотекой?
это довольно просто: ваши матрицы являются мажорными строками.
Так много людей используют мажорные строки или транспонированные матрицы, что забывают, что матрицы не ориентированы таким образом естественным образом. Таким образом, они видят матрицу перевода следующим образом:
1 0 0 0
0 1 0 0
0 0 1 0
x y z 1
Это транспонированная матрица перевода . Это не то , что нормальный перевод матрица выглядит. Перевод идет в 4-й столбце , а не четвертая строка. Иногда, вы даже можете увидеть это в учебниках, что это полная фигня.
Легко узнать, является ли матрица в массиве строкой или столбцом. Если это главная строка, то перевод сохраняется в 3, 7 и 11-м индексах. Если это главный столбец, то перевод сохраняется в 12, 13 и 14-м индексах. Нулевые базовые показатели конечно.
Ваше заблуждение связано с убеждением, что вы используете матрицы с основными столбцами, тогда как на самом деле вы используете матрицы с основными рядами.
Утверждение, что столбец строки по сравнению с основным является Notational конвенции только совсем верно. Механика умножения матриц и умножения матриц / векторов одинакова независимо от соглашения.
Какие изменения смысл результатов.
Матрица 4х4 - это всего лишь сетка чисел 4х4. Это не обязательно относится к изменению системы координат. Однако после того, как вы присвоите значение определенной матрице, вам теперь нужно знать, что в ней хранится и как ее использовать.
Возьмите матрицу перевода, которую я показал вам выше. Это действительная матрица. Вы можете хранить эту матрицу в float[16]
в одном из двух способов:
float row_major_t[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1};
float column_major_t[16] = {1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1};
Тем не менее, я сказал, что этот перевод матрица является неправильным, так как перевод в неправильном месте. Я специально сказал, что оно транспонировано относительно стандартного соглашения о том, как строить матрицы перевода, которое должно выглядеть следующим образом:
1 0 0 x
0 1 0 y
0 0 1 z
0 0 0 1
Давайте посмотрим на то, как они хранятся:
float row_major[16] = {1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1};
float column_major[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1};
Обратите внимание, что column_major
это точно так же, как row_major_t
. Итак, если мы возьмем правильную матрицу перевода и сохраним ее как главную-колонку, это будет то же самое, что транспонировать эту матрицу и сохранить ее как главную-строку.
Это то, что подразумевается под «условным обозначением». На самом деле существует два набора соглашений: хранение памяти и транспонирование. Память хранится в столбце по отношению к основной строке, а транспонирование нормальное и транспонированное
Если у вас есть матрица, которая была сгенерирована в основном порядке строк, вы можете получить тот же эффект, транспонируя основной столбец, эквивалентный этой матрице. И наоборот.
Умножение матриц можно выполнить только одним способом: при заданных двух матрицах в определенном порядке вы умножаете определенные значения вместе и сохраняете результаты. Теперь, A*B != B*A
но фактический исходный код для A*B
такой же, как код для B*A
. Они оба запускают один и тот же код для вычисления вывода.
Код умножения матриц не заботится о том, хранятся ли матрицы в главном или главном порядке строк.
Этого нельзя сказать о умножении вектора на матрицу. И вот почему.
Вектор / матричное умножение - это ложь; это не может быть сделано. Тем не менее, вы можете умножить матрицу на другую матрицу. Таким образом, если вы делаете вид, что вектор является матрицей, тогда вы можете эффективно выполнять умножение вектора на матрицу, просто выполняя умножение матрицы на матрицу.
Вектор 4D можно рассматривать как вектор-столбец или вектор-строку. Таким образом, вектор 4D можно рассматривать как матрицу 4x1 (помните: в матричной нотации счетчик строк идет первым) или матрица 1x4.
Но вот в чем дело: учитывая две матрицы A и B, A*B
определяется только в том случае, если количество столбцов в A равно количеству строк в B. Следовательно, если A является нашей матрицей 4x4, B должна быть матрицей с 4 строками. в этом. Следовательно, вы не можете выполнить A*x
, где x - это вектор-строка . Точно так же вы не можете выполнить, x*A
где x - вектор-столбец.
Из-за этого большинство математических математических библиотек делают это предположение: если вы умножаете вектор на матрицу, вы действительно хотите выполнить умножение, которое действительно работает , а не то, которое не имеет смысла.
Определим для любого четырехмерного вектора x следующее. C
должна быть матричной векторной формой столбца x
и R
должна быть матричной векторной формой строки x
. Учитывая это, для любой матрицы 4x4 A A*C
представляет матрицу, умножающую A на вектор-столбец x
. И R*A
представляет матрицу, умножающую вектор-строку x
на А.
Но если мы посмотрим на это с использованием строгой математической математики, мы увидим, что они не эквивалентны . R*A
не может быть таким же, как A*C
. Это потому, что вектор-строка - это не то же самое, что вектор-столбец. Они не одна и та же матрица, поэтому они не дают одинаковых результатов.
Тем не менее, они связаны друг с другом. Это правда R != C
. Однако верно также и то , где T - операция транспонирования. Две матрицы являются транспонированными друг для друга.R = CT
Вот забавный факт. Так как векторы рассматриваются как матрицы, они тоже имеют столбец против ряда-главного вопроса для хранения. Проблема заключается в том, что они оба выглядят одинаково . Массив с плавающей точкой одинаков, поэтому вы не можете определить разницу между R и C, просто взглянув на данные. Только способ отличить это от того, как они используются.
Если у вас есть какая - либо две матрицы А и В, и А хранятся в виде строки-основная и B в качестве столбцов, умножая их является совершенно бессмысленным . Вы получаете ерунду как результат. Ну не совсем. Математически, что вы получаете эквивалент делать . Или ; они математически идентичны.AT*B
A*BT
Следовательно, умножение матриц имеет смысл, только если две матрицы (и помните: умножение вектора / матрицы - это просто умножение матриц) хранятся в одном и том же главном порядке.
Итак, является ли вектор-столбец мажор или мажор строки? Это не так, и ни один, как было сказано ранее. Это основной столбец, только когда он используется в качестве матрицы столбцов, и это основной ряд, когда он используется в качестве матрицы строк.
Поэтому, если у вас есть матрица A , которая не является столбец основных, x*A
средств ... ничего. Ну, опять же , это значит , но это не то , что вы действительно хотели. Кроме того , это транспонированная умножение , если это строка-мажор.x*AT
A*x
A
Таким образом, порядок вектора / матричного умножения делает изменения, в зависимости от вашего основного упорядочения данных (и вы используете ли транспонированные матрицы).
Почему в следующем фрагменте кода делает г! = R2
Потому что ваш код сломан и глючит. Математически . Если вы не получите этот результат, то либо ваш тест равенства неправильно (вопросы точности с плавающей точкой) или ваш матричный код умножения нарушается.A * (B * C) == (CT * BT) * AT
почему POS3! = поз для
Потому что это не имеет смысла. Единственный способ быть правдой будет, если . И это верно только для симметричных матриц.A * t == AT * t
A == AT