2010-05-31 2 views
4

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

Контекст заключается в том, что я программирую робот для RoboCup 3D league. Я кодирую его на C#, но он должен работать в Mono. В идеале я бы не использовал никаких существующих графических библиотек для этого (WinForms/WPF/XNA), поскольку все, что мне действительно нужно, - это аккуратное подмножество матричных преобразований.

В частности, мне нужны переводы и повороты x/y/z, а также способ объединения нескольких преобразований в одну матрицу. Затем это будет применено к моему собственному Vector3, чтобы произвести преобразованный Vector3.

Я читал разные советы об этом. Например, some моделирует преобразование с матрицей 4x3, others с матрицей 4x4.

Кроме того, некоторые примеры показывают, что вам нужно четвертое значение для матрицы вектора 1. Что происходит с этим значением, когда оно включено в вывод?

 
      [1 0 0 0] 
[x y z 1] * [0 1 0 0] = [a b c d] 
      [0 0 1 0] 
      [2 4 6 1] 

Части я пропавший без вести, являются:

  • Каких размеров моих матрицы должны быть
  • композитинга преобразования пути умножения матриц преобразования вместе
  • Преобразования 3D-векторов с результирующей матрицей

Поскольку я в основном просто хочу, чтобы это сработало, любой psuedo-код был бы Великий. Информация о том, какие значения матрицы выполняют то, какие преобразования достаточно четко определены на многих страницах, поэтому не стоит обсуждать здесь, если вы не очень заинтересованы :)

ответ

6

3 x 3 матрицы могут кодировать преобразования, такие как вращение и отражение, но не перевод , Для этого вам нужно добавить четвертый элемент и представить свои векторы в терминах homogenous coordinates. В некоторых целях можно использовать неквадратные матрицы, но если вы хотите, чтобы они могли составить их в любом порядке, они должны быть квадратными (потому что вы можете только умножать две матрицы, если число столбцов в первом равно количество строк во втором).

Таким образом, для ваших целей, вы должны использовать матрицы 4x4 и 4-элементные однородные векторы, добавив четвертый ж координат со значением 1.

Применив преобразование в кучу векторов просто вопрос умножения ,

Традиционно векторы представлены как columns, а матрица - слева. Вы представляете их выше как rows и умножаетесь справа. Оба действительны, но матрица преобразования должна быть перенесена между этими двумя случаями. Матрица, которую вы показываете, имеет значения сдвига внизу, что верно для вашего порядка умножения.

После того, как векторы были трансформированы, вам нужно разделить через по ж координат в масштабе х, у и г обратно к обычным 3-пространстве.

В C-МОГ псевдокод, используя вектор-строки конвенцию:

Vector transform (Vector v, Matrix m) 
{ 
    Vector result; 
    for (int i = 0; i < 4; ++i) 
     result[i] = v[0] * m[0][i] + v[1] * m[1][i] + v[2] + m[2][i] + v[3] * m[3][i]; 
    result[0] = result[0]/result[3]; 
    result[1] = result[1]/result[3]; 
    result[2] = result[2]/result[3]; 
    return result; 
} 

Последовательность преобразований может быть составлена ​​путем умножения матриц для каждых вместе в своей очереди. Обратите внимание, что умножение матрицы составляет , а не коммутативное, поэтому порядок, в котором вы умножаете значение, важен. В свою очередь это означает, что важно, умножите ли вы векторы строк слева или столбцы справа. Если умножить х В х С, а затем с помощью векторов колонок, что такое же, как выполнять преобразование С, а затем B, а затем, наконец, A. С векторами строк это A сначала, затем B, а затем C. Поэтому важно, чтобы все было согласовано при построении, составлении и применении ваших преобразований.

Опять же, в псевдокоде, которые должны быть согласованы с transform выше:

Matrix compose (Matrix first, Matrix second) 
{ 
    Matrix result; 
    for (int i = 0; i < 4; ++i) 
     for (int j = 0; j < 4; ++j) 
      result[i][j] = first[i][0] * second[0][j] 
          + first[i][1] * second[1][j] 
          + first[i][2] * second[2][j] 
          + first[i][3] * second[3][j]; 
    return result; 
} 
+0

Спасибо большое за подробный ответ. Отлично! –

+0

Ваша точка зрения о необходимости квадратных матриц для их объединения имеет смысл, но эта статья http://www.oocities.com/evilsnack/matrix.htm (которая обсуждает реализацию в POV-RAY) заставляет это звучать как 4x3 - все они используют. Не знаю, почему. Могли бы они каким-то образом нормализоваться с 4x4 до 4x3, а затем затмевать с векторными матрицами 1x3, вместо того, чтобы нормализовать результат 1x4 до 1x3? Это вещь для исполнения? –

+0

Документ утверждает, что они используют внутри себя 4x4, хотя, вероятно, в матричном мультикодном коде есть определенная оптимизация. Но описанный 4x3 - это внешний интерфейс. POV-RAY использует созданный пользователем текстовый файл для определения сцены для рендеринга, поэтому уменьшение количества данных, которые пользователь должен вводить вручную, экономит время и снижает вероятность ошибки. Стандартные преобразования имеют дальний столбец (0 0 0 1), и когда они объединены, результат также имеет этот дальний столбец, поэтому можно сохранить несколько операций, предположив это. Стоимость заключается в том, что у вас есть не общая матричная реализация. – walkytalky

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