Шаг 56 - Что такое матрица?

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

Матрица - это множество чисел, сгруппированных в колонки и столбцы. Здесь изображены две матрицы: Матрица А и Матрица В.

56_1.gif (1163 b)

Матрица А - это матрица 2х3 (то есть у нее две строки и три столбца), тогда как матрица В - это матрица 3х3. Мы можем получить доступ к элементу матрицы А, используя запись А[m,n], где m - это строка, а n - столбец. Элемент в верхнем углу матрицы А будет обозначаться А[0,0] и он равен единице.

Произведение операций над матрицами

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

Для примера, рассмотрим сложение двух матриц размерностью 2х3 - матрицы А и матрицы С:

56_2.gif (650 b)

При сложении матриц А и С нужно складывать каждый из элементов m, n. Суммы элементов займут в результирующей матрице соответствующие места:

56_3.gif (896 b)

Мы также можем умножить матрицу на скаляр k. Например, чтобы умножить матрицу А на 3, мы должны умножить на 3 каждый ее элемент.

56_4.gif (725 b)

Теперь поговорим об умножении двух матриц. Эта операция немного отличается от умножения на скалярную величину. Вы должны запомнить несколько правил:

Умножение матрицы m x n на матрицу n x r может быть описано алгоритмически следующим образом:

  1. Для каждой строки первой матрицы:
    Умножить строку на столбец другой матрицы поэлементно. Сложить полученный результат;
  2. Поместить результат в позицию [i,j] результирующей матрицы, где i - это строка первой матрицы, а j - столбец второй матрицы.

Для простоты посмотрите на рисунок:

56_5.gif (4629 b)

Мы можем это сделать намного проще, написав программу на Си. Давайте определим матрицу 3х3 и напишем функцию, умножающую матрицы. Ниже показан исходный код:

// общая структура матрицы
typedef struct matrix_typ
{
	float elem[3][3];	// место для хранения матрицы
} matrix, *matrix_ptr;

void Mat_Mult3x3(matrix_ptr matrix_1, matrix_ptr matrix_2,
	matrix_ptr result)
{
	index i, j, k;

	for(i=0; i < 3; j++)
	{
		for(j=0; j < 3; j++)
		{
			result[i][j] = 0;	// инициализация элемента
			for(k = 0; k < 3; k++)
			{
				result->elem[i][j] += matrix_1->elem[i][k]
					* matrix_2->elem[k][j];
			} // конец цикла по k
		} // конец цикла по j
	} // конец цикла по i
} // конец функции

Единичная матрица

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

Говоря попросту, нам нужно иметь матрицу размерностью m x n, которую назовем матрицей I. Умножая на нее любую другую матрицу, мы должны получить исходную. Этой матрицей будет квадратная матрица, по главной диагонали которой записаны единицы, а все остальные элементы равны нулю:

56_6.gif (471 b)

Если мы умножим матрицу А на матрицу I,

56_7.gif (824 b)

то результатом будет исходная матрица А:

56_8.gif (154 b)

Использование матриц в играх

Прелесть матриц состоит в том, что Вы можете объединить все операции в одну матрицу, описывающую перемещение, масштабирование и вращение.

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

Главная матрица перемещений

Главной матрицей перемещений будем называть такую матрицу, в которой x_translation и y_translation - это коэффициенты перемещения объекта по осям Х и Y. Вот как она выглядит:

56_9.gif (727 b)

Главная матрица масштабирования

Главная матрица масштабирования - это такая матрица, в которой scale_x и scale_y - это коэффициенты масштабирования объекта по координатам х и y:

56_10.gif (576 b)

Такая матрица позволяет выполнять неоднородное масштабирование - мы можем задать один масштаб по оси Х и другой - по оси Y. Таким образом, если мы хотим масштабировать объект однородно, то должны задать scale_x = scale_y.

Главная матрица поворотов

В главной матрице поворотов angle - это угол, на который Вы хотите повернуть объект:

56_11.gif (893 b)

Общая матрица масштабирования, поворотов и перемещений

Наступает торжественный момент. Теперь мы возьмем матрицы перемещения, масштабирования и поворота и перемножим их (получим конкатенацию), чтобы получить общую матрицу, реализующую все три функции сразу. Окончательно матрица будет выглядеть так:

56_12.gif (1468 b)

Если Вы теперь умножите вершины объекта на эту матрицу, то получите перемещенный, повернутый и масштабированный объект. Не слабо, а?


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Хавов Евгений Валерьевич - 28.08.2002