Преобразования в компьютерной графике
Каждая трансформация фигуры на экране — это умножение её вершин на матрицу преобразования.
Геометрическое преобразование фигуры — это применение одной и той же матрицы ко всем её вершинам; форма меняется согласованно, потому что преобразование линейно.
Когда в игре или редакторе вы поворачиваете спрайт, движок не пересчитывает картинку «на глаз» — он умножает координаты вершин на матрицу поворота. Соберём раздел про матрицы воедино на практичном примере: повернём и масштабируем многоугольник.
Фигура как набор вершин
Квадрат — это четыре точки. Чтобы повернуть его на $90°$, применим матрицу поворота к каждой вершине. Композиция (например, повернуть и сразу растянуть) — это произведение матриц, посчитанное один раз и применённое ко всем точкам.
import math
def matvec(A, v):
return [sum(A[i][j] * v[j] for j in range(len(v)))
for i in range(len(A))]
def matmul(A, B):
return [[sum(A[i][t] * B[t][j] for t in range(len(B)))
for j in range(len(B[0]))] for i in range(len(A))]
rot90 = [[0, -1], [1, 0]]
scale2 = [[2, 0], [0, 2]]
T = matmul(scale2, rot90) # сначала повернуть, потом увеличить
square = [[1, 0], [0, 1], [-1, 0], [0, -1]]
for p in square:
print(p, "->", matvec(T, p))Вывод:
[1, 0] -> [0, 2] [0, 1] -> [-2, 0] [-1, 0] -> [0, -2] [0, -1] -> [2, 0]
Что произошло с квадратом
Каждая вершина повернулась на $90°$ и удвоилась по длине. Точка $(1, 0)$ уехала вверх в $(0, 2)$, $(0, 1)$ — влево в $(-2, 0)$. Квадрат повернулся и стал вдвое больше, оставшись квадратом — линейность сохранила форму. Матрицу $T$ мы посчитали один раз, а применили ко всем вершинам: в реальной графике так обрабатывают тысячи точек.
Как работает под капотом
Реальные движки используют чуть больший приём — однородные координаты: к двумерной точке добавляют третью единичную координату, что позволяет уместить в одну матрицу $3 \times 3$ не только повороты и масштаб, но и параллельный перенос (который сам по себе не линеен). Тогда любую цепочку «повернуть, сдвинуть, масштабировать» сворачивают в одно матричное произведение и применяют к вершинам за один проход. Это объясняет, почему графические процессоры заточены именно под умножение матриц на векторы — это самая частая операция в рендеринге.
Частые ошибки
- Перепутать порядок композиции. $T = S \cdot R$ означает «сначала $R$, потом $S$»; обратный порядок даст другой результат.
- Применять преобразование к фигуре «целиком», а не к каждой вершине. Матрица действует на точки (векторы), а форма получается из их совокупности.
- Пытаться задать параллельный перенос матрицей $2 \times 2$. Для этого нужны однородные координаты.
Итог
- Преобразование фигуры = умножение каждой её вершины на матрицу.
- Композицию преобразований сворачивают в одно матричное произведение.
- Линейность сохраняет форму: квадрат остаётся квадратом, прямые — прямыми.
- Однородные координаты позволяют включить и параллельный перенос в одну матрицу.