{{notification.text}}

MirGames

Вне зависимости от платформы, которую вы решил использовать, знание основ 3D математики необходимо. Вы еще не успели ее освоить? Не беда! В качестве базы вполне достаточно знаний, которые вы почерпаете из этой статьи.

Точки (Points) и Отрезки (Segments)

Любая точка в 3D программировании задается набором из 3-х координат по ортогональным (взаимно перпендикулярным) осям (x, y, z) соответственно. Точками задаются также координаты вершин объекта.

Отрезок – часть прямой, соединяющая две точки. Задается координатами концов.

Длина отрезка вычисляется по теореме Пифагора:len = sqrt{(x_2-x_1)^2+(y_2-y_1)^2+(z_2-z_1)^2}, где (x_1,y_1,z_1) и (x_2,y_2,z_2) – координаты концов отрезка

Отрезок и точка имеют расположение в пространстве.

Векторы (Vectors)

Вектором называется направленный отрезок.

Обычно в 3D программировании равными считаются все вектора, имеющие одинаковую длину (или модуль вектора) и направление. Т.е. у вектора в данном понимании нет расположения, в отличие от отрезка или точки. Поэтому любой вектор можно задать лишь направлением (т.е. единичным, нормализованным вектором или ортом) и его длиной.

Но обычно вектор задается лишь координатами (по 3-м осям) конца вектора, считая, что начало вектора находится в начале координат (0, 0, 0) (вспомните, что для вектора не важно месторасположение). Именно такое восприятие понятия вектора рассматривается в данной статье и используется в 3D программировании.

Пусть vec{A}(x_1,y_1,z_1). Тогда модуль этого вектора вычисляется следующим образом: delim{|}{vec{A}}{|} = sqrt{{x_1}^2+{y_1}^2+{z_1}^2}

Иногда под словом “вектор” подразумевают просто линейный массив т.к. именно в таком виде векторы задаются в 3D программировании.

На самом деле задаются в виде массива 1x4 (x,y,z,w). Такой способ задания связан с матрицами – о них ниже. Но для нас важны лишь первые три компонента (x,y и z) вектора. Поэтому пока опустим 4-й компонент (w).

Вектор (0,0,0) не имеет направления и является точкой без месторасположения. Такой вектор называется нулевым вектором или нуль-вектором.


Действия над векторами
Сложение (addition) двух векторов.

Суммой двух векторов vec{A}(x_1,y_1,z_1) и vec{B}(x_2,y_2,z_2) называется вектор vec{C}(x_1+x_2,y_1+y_2,z_1+z_2).

Определение противоположных векторов
Два вектора называются противоположными, если их сумма равна нуль-вектору.

Умножение (multiplication) вектора на число

Произведением вектора vec{A}(x_1,y_1,z_1) на число lambda называется вектор vec{A}prime(lambda x_1,lambda y_1,lambda z_1)

Скалярное произведение (scalar multiplication или dot product) двух векторов.

Скалярным произведением двух векторов vec{A}(x_1,y_1,z_1) и vec{B}(x_2,y_2,z_2) называется такое число lambda=x_1 x_2+y_1 y_2+z_1 z_2 и обозначается как vec{A}vec{B} или (vec{A},vec{B}).

Также можно вычислять по формуле vec{A}vec{B}=delim{|}{vec{A}}{|}delim{|}{vec{B}}{|}cos(hat{vec{A}vec{B}})

Следствие
cos(hat{vec{A}vec{B}})={x_1 x_2+y_1 y_2+z_1 z_2}/{delim{|}{vec{A}}{|}delim{|}{vec{B}}{|}}

Скалярное произведение кроме всего прочего используется для проверки ортогональности (перпендикулярности) двух векторов. Так, если: vec{A}vec{B}=0, то vec{A} и vec{B} – ортогональны.

Векторное произведение (vector multiplication или cross product) двух векторов.

Векторным произведением двух векторов vec{A} и vec{B} (обозначается vec{A}* vec{B} или delim{[}{vec{A},vec{B}}{]}) называется вектор vec{C}, обладающий следующими свойствами:

  1. delim{|}{vec{C}}{|}=delim{|}{vec{A}}{|} delim{|}{vec{B}}{|} delim{|}{sin(hat{vec{A},vec{B}})}{|}
  2. vec{C}ortho vec{A} и vec{C}ortho vec{B}
  3. vec{A},vec{B},vec{C} – правая тройка (т.е. если смотреть из начала vec{C} к концу, то для совмещения vec{A} к vec{B} необходимо вращать vec{A} по часовой стрелке вокруг оси vec{C})

По другому:

delim{[}{vec{A}(x_1,y_1,z_1),vec{B}(x_2,y_2,z_2)}{]}=vec{C}(x_3,y_3,z_3), где
x_3=y_1z_2-z_1y_2
y_3=z_1x_2-x_1x_2
z_3=x_1y_2-y_1x_2

Заметим, что для векторного произведения не действительно свойство коммутативности т.к. vec{A}*vec{B}=~-vec{B}*vec{A}, в то время как для скалярного произведения vec{A}vec{B}=vec{B}vec{A}.

Векторное произведение играет очень важную роль в 3D программировании т.к. позволяет вычислять нормальные вектора (или просто нормали) к граням, т.е. вектор, перпендикулярный грани. Нормали используются при расчете освещения, сглаживания, обработке столкновений и еще много для чего.

Кроме того, векторное произведение помогает при определении взаимного расположения двух векторов. Так, если vec{A}*vec{B}=0, то векторы vec{A} и vec{B} – коллинеарны.

Смешанное произведение двух векторов

Существует, также, смешанное произведение трех векторов:

(delim{[}{vec{A},vec{B}}{]},vec{C}) = (vec{A},delim{[}{vec{B},vec{C}}{]})

Смешанное произведение трех векторов – это число, равное объему параллелепипеда, построенного на векторах vec{A}, vec{B} и vec{C}.

Если смешанное произведение трех векторов равно нулю, то эти векторы компланарны, т.е. лежат в одной плоскости.

Векторы занимают очень важное место в программировании 3D графики, так как являются, по сути, ее основой (вспомним, что это векторная графика). Более детально вы ознакомитесь со значением векторов при изучении выбранной платформы.

Матрицы (Matrices)

Матрицей размерности mxn называется прямоугольная таблица, имеющая m строк и n столбцов и заполненная элементами одного типа.

В 3D программировании рассматриваются лишь матрицы, заполненные числами с фиксированными или плавающими точками.

Вектор, например, является матрицей размерности 1x3.

Матрицы записываются в таком виде:

A=(matrix{3}{3}{a_11 a_12 a_13 a_21 a_22 a_23 a_31 a_32 a_33}) Российский стандарт записи матриц

A=delim{[}{matrix{3}{3}{a_11 a_12 a_13 a_21 a_22 a_23 a_31 a_32 a_33}}{]} Западный способ записи матриц

Хотя, думаю, любой из способов записи будет понятен во всем мире.

Чтобы понять цели использования матриц в 3D программировании, разберемся сначала с действиями над ними.

Действия над матрицами
Сложение (addition) двух матриц.

Сложение определено лишь для матриц одинаковой размерности.

Пример:

A = delim{[}{matrix{2}{2}{a_11a_12a_21a_22}}{]} B = delim{[}{matrix{2}{2}{b_11b_12b_21b_22}}{]}~A+B = delim{[}{matrix{2}{2}{{a_11+b_11}{a_12+b_12}{a_21+b_21}{a_22+b_22}}}{]}

Умножение матрицы на число (multiplication of matrix by scalar).

Пример:

A = delim{[}{matrix{2}{2}{a_11a_12a_21a_22}}{]}, k — действительное число, т.е. k in bbR, тогда kA=delim{[}{matrix{2}{2}{{ka_11}{ka_12}{ka_21}{ka_22}}}{]}

Умножение двух матриц (matrix multiplication).

Умножение – самое важное действие над матрицами в 3D программировании. Значение этого действия объяснено ниже.

Сразу необходимо предупредить – умножение двух матриц не кажется естественным очевидным.

Причины введения именно такого определения умножения связаны с математическими рассуждениями, не имеющими прямого отношения к 3D графике.

Однако возможности, которые предоставляет такое умножение матриц для 3D, просто потрясающи.

Итак, умножение двух матриц A mxn и B kxl, определено только для n=k.

A=delim{[}{matrix{3}{3}{{a_11}{cdots}{a_{1n}}{cdots}{ddots}{cdots}{a_m1}{cdots}{a_mn}}}{]} B=delim{[}{matrix{3}{3}{{b_11}{cdots}{b_{1l}}{cdots}{ddots}{cdots}{b_n1}{cdots}{b_nl}}}{]}

Тогда C=AB. ⇒ C – матрица размерности mxl. Cij=Ai1B1j+Ai2B2j+…+AinBni (i-номер строки, j –номер столбца).

Волшебное правило умножения матриц
Запомните «волшебное правило умножения матриц» (© Нагорный С. В., мой преподаватель алгебры):
«Строка на столбец, строка на столбец…»

Примеры:

Матрица 1x2 умножается на матрицу 2x1

Перемножение матриц 2x2

Умножение двух матриц, очевидно, в общем случае не коммутативно.

Транспонирование (transpose) матрицы.

Транспонированной матрицей A называется матрица AT, строки которой равны соответствующим столбцам матрицы A, а столбцы – соответствующим строкам A.

Пример:

Особые виды матриц
Единичная (identity) матрица.

Единичная матрица определена лишь для квадратных матриц.

Единичной матрицей размерности n называется такая матрица E (или I), чтоAE=EA=A, где A – матрица размерности nxn.

Матрица E имеет вид:

Действительно, при умножении такой матрицы на любую матрицу nxn получается сама эта матрица.

Обратная (inverse) матрица.

Обратная матрица определена лишь для квадратных матриц.

Обратной матрицей для матрицы A (nxn) называется такая матрица A-1(nxn), что AA-1=A-1A=E

Не стоит забывать, что для матриц не определено действие деления, поэтому A-1 не имеет ничего общего с 1/A (эта запись вообще не имеет смысла).

Нахождение обратной матрицы – очень сложная задача, но во всех библиотеках трехмерной графики (будь то OpenGL, Direct3D или что-то еще) обязательно есть функция для нахождения таких матриц. Читайте help'ы, manual'ы и так далее.

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

Благодаря возможностям, часть которых уже была рассмотрена выше, а часть будет рассмотрена далее, в 3D программировании используются квадратные матрицы.

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

Поэтому далее рассматриваются лишь матрицы размерности 4x4.

Кроме того, точки хранятся в виде линейного массива 1x4 (x,y,z,w).

Реальные координаты точки в 3D пространстве , компонент w является масштабом (зачем это нужно станет понятным чуть позже).

Обычно для точек w=1.

Вектора также задаются в виде линейного массива 1x4 (x,y,z,w), но компонент w у векторов всегда равен 0.

Так как вектора и точки имеют вид матрицы 1x4, то их можно умножать на матрицы 4x4.

Транслятивная матрица (translation matrix).

Имеет вид:

Если умножить точку A (x1, y1, z1, 1) на транслятивную матрицу, то получим новую точку A' (x1+ x0, y1+ y0, z1+ z0, 1), т.е. переместим точку A на x0 единиц по оси Ox, на y0 единиц по оси Oy и на z0 единиц по оси z.

Направление перемещения зависит от знака.

Заметим также, что т.к. вектор не имеет месторасположения в пространстве, он не должен транслироваться, и действительно, так как компонент w у вектора равен 0, то при умножении вектора на транслятивную матрицу вектор не изменится!

Теперь мы смело можем умножить все элементы сцены (вершины (которыми задаются все отрезки, многогранники и т.д.) и векторы (которыми задаются оси вращения, источники света, нормали и еще много чего)) на транслятивную матрицу. Все объекты, которым нужно переместиться сделают это, а остальные (объекты, связанные с векторами) останутся, как были. Получился эффект перемещения камеры на (-x0, -y0, -z0) единиц.

Именно для этого и введена компонента w.

Матрицы вращения (rotation matrices).

Имеют вид:

Умножение объекта (вектора или точки) на одну из этих матриц приведет к вращению этого объекта вокруг оси Ox, Oy или Oz соответственно.

Для вращения вокруг произвольной оси используется последовательное умножение объекта на угол, образуемый проекцей с осью Ox, Oy, Oz на соответствующие матрицы вращения.

Вам не придется вычислять эти углы самому, во всех библиотеках 3D графики имеются все необходимые для этого функции.

Матрица масштабирования (scaling matrix).

Имеет вид:

Масштабирует объект (вектор или точку) в x0 раз по оси Ox, в y0 раз по оси Oy, в z0 раз по оси Oz.

Матрица приведения базиса системы (matrix of reduction of basis of system).

Базисом системы координат называется совокупность векторов, через которую выражаются все объекты данной системы координат.

В 3D графике используется несколько вариантов базиса, например:

Когда нам нужно преобразовать объект, сохраненный в одном базисе в другой базис, нам необходимо умножить его на соответствующую матрицу приведения базиса.

Все такие матрицы имеют различный вид и равносильны комбинации нескольких матриц трансляции, вращения и масштабирования.

Во всяком случае, библиотеки 3D графики содержат все необходимые функции для таких преобразований.

Благодаря приведенным выше возможностям, механизм матриц становится незаменимой вещью при программировании 3D графики.

Заключение

Конечно, приведенный выше материал – это далеко не все математические элементы, необходимые для программирования 3D графики.

Впереди еще лучи, плоскости, многогранники и еще много-много чего. Но это основа, база для последующих знаний.

Теперь уже можно начинать изучение самой платформы вывода 3D графики. В хорошей литературе обязательно будет приведена информация по необходимым разделам математики, не вошедшая в данную статью.

Успехов вам в изучении 3D графики!

Рекомендуемая литература

Подойдет любой подробный учебник по линейной алгебре (я учился по книге «Лекции по алгебре» Д. К. Фаддеева, однако, возможно, ее текст покажется сложным для восприятия).

Сейчас в продаже имеется множество хороших книг по этой теме.

Кроме того, для последующего изучения Direct3D (если вы решили изучать именно Direct3D и ваш язык – C++) я рекомендовал бы вам книгу “Introduction to 3D Game Programming with DirectX 9.0” by Frank D. Luna (не знаю, переведена ли эта книга на русский язык – я читал по-английски). Там, кроме всего прочего, рассмотрены также и необходимые разделы математики, не описанные здесь.

Этот раздел книги будет полезен для всех – вне зависимости от языка программирования и платформы 3D графики, которую вы используете.

11.11.04 00:41