LerpworksAcademy
На этой странице

Урок по шагам

Векторы: стрелки, которые складывают

19 шагов

  • Зачем это
  • Вектор — это шаг
  • Сложение: два шага подряд
  • Вычитание: как дойти от A до B
  • Умножение на число: длиннее, короче, назад
  • Длина: теорема Пифагора без зубрёжки
  • Нормализация: направление без расстояния
  • Три числа — одна стрелка
  • Где ломается
  • Связи: та же идея в других областях
  • Главное

Математика и физика › Векторы

Векторы: стрелки, которые складывают

Этот урок есть в курсе «Математика на пальцах».

Вектор — это не формула и не «направленный отрезок» из учебника, а шаг: сколько пройти и куда. На таких шагах держится почти вся математика игр: положение и скорость, направление на врага, ветер, нормаль поверхности, даже цвет пикселя. Разберём, что такое вектор на картинке, и четыре действия с ним: сложить, вычесть, умножить на число и узнать длину. После них формулы из шейдеров и игровой логики читаются как обычные фразы.

Зачем это

Открой любой материал, настройку движения персонажа или урок по графике — там векторы. «Позиция плюс скорость, умноженная на время». «Нормализовать направление на цель». «Скалярное произведение нормали и света». Если за словом «вектор» не стоит картинка, это набор заклинаний, и его приходится зубрить.

В школе векторы обычно дают как правила для чисел: складывай координаты, считай корень из суммы квадратов. Правила верные, но без картинки они не держатся в голове. Здесь наоборот: сначала картинка и смысл, потом правило — и станет видно, почему оно именно такое.

Вектор — это шаг

Представь карту сокровищ: «от старого дуба — три шага на восток и два на север». Это инструкция, как переместиться. В ней две вещи: куда идти и сколько. На картинке её рисуют стрелкой: хвост — откуда шагаешь, наконечник — куда пришёл.

Такая инструкция и есть вектор. Записывают его числами — сколько пройти вдоль каждой оси: (3, 2) — три вправо и два вверх. Направления, вдоль которых отсчитывают шаги, называют осями: x смотрит вправо, y — вверх. Сами числа называют компонентами вектора. В 3D добавляется третья ось, и вектор записывают тремя числами: (x, y, z).

Главное свойство вектора: у шага нет места. «Три на восток и два на север» можно пройти от дуба, от камня, от реки — это одна и та же инструкция. Поэтому стрелку можно переносить куда угодно, и вектор от этого не меняется: он тот же, пока у стрелки та же длина и то же направление.

Попробуй

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


Заметь две вещи. Если тащить стрелку за хвост, числа не меняются: вектор не знает, где он нарисован. А отрицательное число — шаг в обратную сторону: (−2, 1) — два влево и один вверх.

Точка и вектор

Тогда что такое точка? Точка — это место: «вот здесь стоит дуб». Вектор — перемещение: «отсюда три шага на восток». Разница такая же, как между адресом дома и объяснением «от остановки направо и до конца улицы».

Но про любую точку можно спросить: каким шагом до неё дойти от начала координат? Точка (5, 3) — это место, куда приводит шаг (5, 3) от начала мира. Поэтому движки хранят точки и векторы одинаково — тремя числами, и в формулах они встречаются рядом. Смысл при этом разный, и он подсказывает, какие действия имеют смысл:

  • точка + вектор = точка: «от дуба три шага на восток» — новое место;
  • точка − точка = вектор: как дойти от одного места до другого;
  • вектор + вектор = вектор: два шага подряд;
  • точка + точка — бессмыслица: «место дуба плюс место реки» зависит от того, где на карте начало отсчёта.

В уроке про пространства видно, как видеокарта отличает одно от другого: у точки есть четвёртое число w = 1, у вектора w = 0.

Сложение: два шага подряд

Сначала три на восток и один на север, потом один на восток и два на север. Куда ты пришёл? На восток всего 3 + 1 = 4, на север 1 + 2 = 3. Итог — (4, 3).

(3, 1) + (1, 2) = (3 + 1, 1 + 2) = (4, 3)

Это всё правило сложения: x с x, y с y. Почему так? Шаги на восток никак не влияют на шаги на север: восточные складываются между собой, северные — между собой. На картинке это «хвост второй стрелки к наконечнику первой»: пройди первую стрелку, от её конца — вторую, и стрелка от начала до конца пути будет суммой.

Порядок не важен. «Сначала первый шаг, потом второй» и «сначала второй, потом первый» приводят в одно место: два пути обходят параллелограмм с разных сторон и сходятся в дальнем углу.

Попробуй

В режиме «Сумма» стрелка b начинается там, где кончилась a, а сумма ведёт от начала до конца пути. Тяни наконечники. Галочка покажет другой порядок: сначала b, потом a. В режиме «Разность» обе стрелки идут из начала, как адреса двух точек, а b − a — шаг от конца a к концу b.


Где это в играх:

  • Движение. Новая позиция = старая позиция + шаг за кадр. Шаг — это скорость, тоже вектор, умноженная на время кадра.
  • Течение и ветер. Лодка гребёт на север, течение сносит её на восток. Куда она плывёт на самом деле, показывает сумма двух векторов.
  • Цвет. Цвет пикселя — тоже вектор из трёх чисел (R, G, B). Свет двух ламп складывается как векторы, канал с каналом: об этом урок про цвет.
  • Сдвиг текстуры. Адрес в текстуре — вектор (u, v). Прибавь к нему небольшой вектор, который растёт со временем, и текстура поплывёт, как вода.

Вычитание: как дойти от A до B

Самый частый вопрос в игре: как дойти отсюда туда? Где враг относительно меня? Куда лететь снаряду? Ответ — вычитание:

шаг от A до B = B − A          // «куда» минус «откуда»

я в (2, 1), враг в (8, 9):   враг − я = (8 − 2, 9 − 1) = (6, 8)

Проверь: если к моей позиции прибавить (6, 8), получится (8, 9) — позиция врага. Вычитание отвечает на вопрос «что нужно прибавить к A, чтобы получить B?».

Порядок здесь важен. Я − враг = (−6, −8): та же стрелка, развёрнутая назад, от врага ко мне. Путаница в порядке — классическая ошибка: враг, который должен бежать к игроку, убегает от него. Правило не нужно зубрить — спроси себя: «куда минус откуда».

В режиме «Разность» в демо выше то же видно на картинке: b − a — стрелка от конца a к концу b.

Умножение на число: длиннее, короче, назад

Шаг (3, 1), сделанный дважды, — это (6, 2). Умножить вектор на число — сделать шаг во столько раз длиннее, не меняя направления. Каждый компонент умножается на это число: удвоенный шаг — это вдвое больше пути на восток и вдвое больше на север.

  • × 2 — вдвое длиннее, направление то же;
  • × 0.5 — вдвое короче;
  • × (−1) — та же длина, обратное направление;
  • × 0 — шага нет: (0, 0).

Обычное число, в отличие от вектора, называют скаляром: оно меняет только масштаб, отсюда и название. Скорость 5 м/с, время кадра 0.016 с, сила ветра 0.3 — скаляры. Самая частая формула движения — направление, умноженное на скорость: «куда» умножить на «насколько быстро».

Попробуй в первом демо ползунок «Умножить на»: стрелка растягивается, сжимается и разворачивается, но остаётся на той же прямой.

Длина: теорема Пифагора без зубрёжки

Шаг (3, 4): три на восток и четыре на север. Если идти не по клеткам, а напрямик, сколько это? Путь по клеткам — 3 + 4 = 7, но по прямой короче. Стрелка, шаг вдоль x и шаг вдоль y образуют прямоугольный треугольник, и длину стрелки даёт теорема Пифагора:

длина² = x² + y²          // 3² + 4² = 9 + 16 = 25
длина  = √(x² + y²)       // √25 = 5

в 3D:   длина = √(x² + y² + z²)

Что это значит на картинке: построй квадраты на всех трёх сторонах треугольника. Площадь квадрата на длинной стороне равна сумме площадей двух других: 25 = 9 + 16. Почему так — в блоке «Под капотом» ниже: там доказательство, в котором нечего зубрить.

Попробуй

Тяни наконечник. На каждой стороне треугольника построен квадрат, внутри — его площадь. Как ни меняй стрелку, большой квадрат равен двум маленьким вместе.


Отсюда самое полезное следствие: расстояние между точками — это длина вектора между ними. Как далеко враг? Длина (враг − я) = длина (6, 8) = √(36 + 64) = 10 метров.

Почему Пифагор: доказательство картинкой
c² a² b²
Слева и справа — одинаковые большие квадраты и одинаковые треугольники с короткими сторонами a и b. Свободное место слева — квадрат на длинной стороне, справа — два квадрата на коротких.

Возьми квадрат со стороной a + b и четыре одинаковых прямоугольных треугольника с короткими сторонами a и b. Разложи их двумя способами. Слева треугольники стоят по углам, и в середине остаётся наклонный квадрат со стороной c — длинной стороной треугольника. Справа те же треугольники сложены в два прямоугольника, и остаются два квадрата: a × a и b × b.

Большой квадрат тот же, треугольники те же — значит, и свободная площадь одна и та же: c² = a² + b². Ничего запоминать не нужно, достаточно помнить картинку.

В 3D правило применяют дважды. Сначала находят длину шага по двум осям, √(x² + y²). Потом эта длина и третье число z снова образуют прямоугольный треугольник, и длина всего шага — √(x² + y² + z²).

Нормализация: направление без расстояния

Часто нужно только «куда», без «сколько»: куда повернуть голову, куда дует ветер, куда смотрит поверхность. Для этого вектор делят на его длину, и остаётся стрелка того же направления длиной ровно 1. Это нормализация, а вектор длиной 1 называют единичным.

направление = вектор / длина

враг − я = (6, 8), длина 10   →   направление = (0.6, 0.8)
бежать к врагу со скоростью 5 м/с:   (0.6, 0.8) × 5 = (3, 4) за секунду   // длина ровно 5

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

Попробуй

Персонаж слева бежит к цели. Тяни цель ближе и дальше и сравни два способа посчитать шаг за секунду. Кружок — где персонаж окажется через секунду.


Единичные векторы в графике повсюду. Нормаль — единичный вектор «куда смотрит поверхность». Направление на солнце — единичный вектор. Их держат длиной 1, потому что тогда скалярное произведение двух таких стрелок даёт чистый угол без примеси длины. Это тема следующего урока.

Три числа — одна стрелка

В движках вектор — это набор из двух, трёх или четырёх чисел. В шейдерах такие наборы называют float2, float3 и float4, в Blueprint Unreal — Vector. Одним и тем же набором записывают вещи, которые на первый взгляд не похожи на стрелки:

ЧтоЧислаКакой это шаг
Позиция(x, y, z)шаг от начала мира до предмета
Скорость(x, y, z) в м/сшаг за одну секунду
Нормаль(x, y, z), длина 1куда смотрит поверхность
Цвет(R, G, B)сколько красного, зелёного и синего
Адрес в текстуре(u, v)шаг от угла текстуры

Поэтому одни и те же действия работают для всего. Умножить цвет на 2 — сделать его вдвое ярче: соотношение каналов то же, поэтому и оттенок тот же. Умножить UV на 2 — это тайлинг: каждый адрес вдвое дальше от угла, и текстура повторяется дважды.

Где ломается

  • Враг несётся к далёкой цели, а у близкой еле ползёт. Шаг посчитан как (цель − я) × скорость, без нормализации: в скорость просочилось расстояние. Нормализуй направление, потом умножай на скорость.
  • Враг убегает вместо того, чтобы догонять. Вычитание в обратном порядке: я − цель вместо цель − я. Проверь: «куда минус откуда».
  • По диагонали персонаж бегает быстрее, чем прямо. Нажаты «вправо» и «вверх», и ввод (1, 1) имеет длину √2 ≈ 1.41 — на 41% больше. Нормализуй ввод или ограничь его длину единицей.
  • Предмет исчезает или ведёт себя странно, когда цель ровно в той же точке. Нормализация нулевого вектора: деление на ноль. Проверяй длину перед нормализацией.
  • Скорость зависит от частоты кадров. Скорость прибавляют к позиции каждый кадр, не умножив на время кадра: при 120 кадрах в секунду всё вдвое быстрее, чем при 60. Об этом урок про движение.
  • Числа сложены правильно, а результат бессмысленный. Сложили две точки или векторы из разных пространств. Точку с точкой не складывают, а векторы сначала переводят в одно пространство.

Главное

  • Вектор — это шаг: сколько пройти и куда. Числа (x, y, z) — сколько шага приходится на каждую ось. Места у вектора нет: стрелку можно переносить.
  • Точка — место, вектор — перемещение. Точка + вектор = точка, точка − точка = вектор, а точку с точкой не складывают.
  • Сложение — два шага подряд: x с x, y с y. Порядок не важен.
  • Вычитание B − A — шаг от A до B, «куда минус откуда». Его длина — расстояние между точками.
  • Умножение на число меняет длину, а минус разворачивает стрелку назад.
  • Длина — теорема Пифагора: √(x² + y² + z²). Чтобы сравнить расстояния, корень можно не считать.
  • Нормализация оставляет направление длиной 1. Скорость = направление × быстрота; без нормализации в неё просачивается расстояние.

Проверь себя

8 вопросов. В профиль идёт лучший результат, проходить можно сколько угодно.

1. Персонаж стоит в точке (2, 1), сундук — в точке (5, 5). Какой вектор ведёт от персонажа к сундуку?

2. Лодка прошла 3 км на восток, потом 4 км на север. Как далеко она от места старта по прямой?

3. Враг бежит к игроку по формуле «шаг = (игрок − враг) × скорость». Что заметит игрок?

4. Что делает нормализация вектора?

5. Что получится, если вектор (2, −1) умножить на −3?

6. Игрок жмёт «вправо» и «вверх» одновременно, ввод — (1, 1). Почему по диагонали он бежит быстрее?

7. Сложили позиции двух домов: (10, 20) + (30, 4) = (40, 24). Что означает результат?

8. Цвет (0.2, 0.4, 0.6) умножили на 2. Что стало с цветом?

Что-то осталось непонятным? Выдели этот кусок текста и нажми «Спросить про это». Вопрос уйдёт автору, и это место перепишут понятнее.