Предположим, вы пишете матричный код, который обрабатывает вращение, перемещение и т. Д. Для трехмерного пространства.
Теперь матрицы преобразования должны быть 4х4, чтобы соответствовать компоненту перевода.
Однако вам не нужно хранить w
компонент в векторе, не так ли?
Даже при разделении перспективы вы можете просто вычислить и сохранить w
вне вектора, а также разделить перспективу, прежде чем вернуться из метода.
Например:
// post multiply vec2=matrix*vector
Vector operator*( const Matrix & a, const Vector& v )
{
Vector r ;
// do matrix mult
r.x = a._11*v.x + a._12*v.y ...
real w = a._41*v.x + a._42*v.y ...
// perspective divide
r /= w ;
return r ;
}
Есть ли смысл хранить w
в классе Vector?
mathematics
vector
projection
bobobobo
источник
источник
r.x = ... + a._14*v.w;
r.y = ... + a._24*v.w;
r.z = ... + a._34*v.w;
r.w = ... + a._44*v.w;
посмотрите на мой ответ для деталейОтветы:
РЕДАКТИРОВАТЬ Отказ от ответственности : Для удобства в этом ответе векторы с w == 0 называются векторами, а с w == 1 - точками. Хотя, как указал FxIII, это не математически правильная терминология. Однако, поскольку суть ответа не в терминологии, а в необходимости различать оба типа векторов, я буду придерживаться этого. По практическим соображениям это соглашение широко используется в разработке игр.
Невозможно провести различие между векторами и точками без компонента w. Это 1 для точек и 0 для векторов.
Если векторы умножаются на аффинную матрицу преобразования 4x4, которая имеет перевод в последней строке / столбце, вектор также будет переведен, что неверно, должны быть переведены только точки. Об этом заботится ноль в компоненте 'w' вектора.
Выделение этой части умножения матрицы на вектор делает это более ясным:
Т.е. было бы неправильно переводить вектор, например ось вращения, результат просто неправильный. Имея ноль 4-го компонента, вы все равно можете использовать ту же матрицу, которая преобразует точки для преобразования оси вращения, и результат будет действительным и его длина сохраняется до тех пор, пока в матрице нет шкалы. Это поведение, которое вы хотите для векторов. Без 4-го компонента вам пришлось бы создать 2 матрицы (или 2 разные функции умножения с неявным 4-м параметром) и сделать 2 разных вызова функций для точек и векторов.
Чтобы использовать векторные регистры современных процессоров (SSE, Altivec, SPU), вы все равно должны передать 4x 32-битные числа с плавающей запятой (это 128-битный регистр), плюс вам нужно позаботиться о выравнивании, обычно 16 байтах. Таким образом, у вас нет возможности сохранить место для 4-го компонента в любом случае.
РЕДАКТИРОВАТЬ: ответ на вопрос в основном
Нужно выбрать один из них, невозможно сохранить только {x, y, z} и при этом использовать только одну функцию умножения матрицы на вектор. XNA, например, использует последний подход, имея 2 функции Transform в своем классе Vector3 , которые называются
Transform
иTransformNormal
Вот пример кода, который демонстрирует оба подхода и демонстрирует необходимость различать оба вида векторов одним из двух возможных способов. Мы переместим игровую сущность с позицией и направлением взгляда в мире, преобразовав ее с помощью матрицы. Если мы не используем компонент 'w', мы больше не можем использовать такое же умножение матрицы на вектор, как показано в этом примере. Если мы все равно это сделаем, мы получим неправильный ответ для преобразованного
look_dir
вектора:Начальное состояние объекта:
Теперь к этой сущности будет применено преобразование с переводом x + 5 и поворотом на 90 градусов вокруг оси y. Правильный ответ после преобразования:
Мы получим правильный ответ, только если будем различать векторы с w == 0 и позиции с w == 1 одним из представленных выше способов.
источник
Если вы создаете класс Vector, я предполагаю, что класс будет хранить описание трехмерного вектора. Трехмерные векторы имеют значения x, y и z. Поэтому, если вашему вектору не нужна произвольная величина w, нет, вы не будете хранить его в классе.
Существует большая разница между вектором и матрицей преобразования. Учитывая, что DirectX и OpenGL имеют дело с матрицами для вас, я обычно не храню матрицу 4x4 в своем коде; скорее, я храню ротации Эйлера (или кватернионы, если хотите - у которых по совпадению действительно есть компонент w) и перевод x, y, z. Если хотите, перевод представляет собой вектор, и вращение технически будет соответствовать и вектору, где каждый компонент будет хранить величину вращения вокруг своей оси.
Если вы хотите глубже погрузиться в математику вектора, евклидов вектор - это только направление и величина. Поэтому, как правило, это представляется тройкой чисел, где каждое число является величиной вдоль оси; его направление подразумевается комбинацией этих трех величин, и величина может быть найдена с помощью формулы евклидова расстояния . Или, иногда, оно действительно сохраняется как направление (вектор с длиной = 1) и величиной (с плавающей точкой), если это удобно (например, если величина меняется чаще, чем направление, может быть удобнее просто изменить это значение, чем взять вектор, нормализовать его и умножить компоненты на новое значение).
источник
Четвертое измерение в трехмерном векторе используется для вычисления аффинных преобразований, которые невозможно будет вычислить, используя только матрицы. Пространство остается трехмерным, так что это означает, что четвертое отображается каким-то образом в трехмерном пространстве.
Карта размеров означает, что разные 4D-векторы указывают одну и ту же 3D-точку. Карта состоит в том, что если A = [x ', y', z'.w '] и B = [x ", y", z ", w"], они представляют одну и ту же точку, если x' / x "= y ' / y "= z '/ z" = w' / w "= α, т.е. компонент пропорционален для одного и того же коэффициента α.
Сказал, что вы можете выразить точку зрения (скажем, (1,3,7)) бесконечными способами, такими как (1,3,7,1) или (2,6,14,2) или (131,393,917,131) или в целом (α · 1, α · 3, α · 7, α).
Это означает, что вы можете масштабировать четырехмерный вектор на другой, представляющий ту же трехмерную точку, так что w = 1: форма (x, y, z, 1) является канонической формой.
Применяя матрицу к этому вектору, вы можете получить вектор, который не имеет w = 1, но вы всегда можете масштабировать результаты, чтобы сохранить их в канонической форме. Таким образом, ответ выглядит так: «Вы должны использовать 4D-векторы при выполнении математики, но не хранить четвертый компонент» .
Это вполне верно, но есть некоторые моменты, которые вы не можете выразить в канонической форме: такие как (4,2,5,0). Эти точки являются особыми, они представляют направленную бесконечную точку и могут быть последовательно нормализованы к единичному вектору: вы можете безопасно перейти к бесконечности и вернуться (даже дважды), не будучи Чаком Норрисом. Вы получите жалкое деление на ноль, если попытаетесь привести эти векторы в каноническую форму.
Теперь вы знаете, так что выбор за вами!
источник
Да, вы делаете. Ваше преобразование неверно для некоторых видов векторов. Вы можете увидеть это в математической библиотеке D3DX - у них есть две разные функции умножения матрицы на вектор, одна для w = 0 и одна для w = 1.
источник
Зависит от того, что вы хотите и нужно. :)
Я бы сохранил его, потому что он необходим для преобразований и тому подобного (вы не можете умножить вектор 3 на матрицу 4x4), хотя, если у вас всегда есть только 1, я думаю, вы могли бы просто подделать его.
источник