Уроки · 23
Точка плюс вектор
В уроке «Смещение» мы прибавляли одно число к одной
координате, и точка сдвигалась в сторону. В уроке
«Направление» появилась уже пара чисел сразу:
direction_x * LENGTH и
direction_y * LENGTH. Это та же самая идея смещения, только по двум
координатам одновременно — такую пару чисел и называют вектором.
Вектор — это не место, а движение
Заголовок раздела «Вектор — это не место, а движение»Сам по себе вектор не говорит, где что-то находится, — он говорит,
на сколько сдвинуться: на столько-то по x, на столько-то по
y. Пока его ни к чему не прибавили, у вектора нет положения на
экране — только направление и длина.
// Вектор — это смещение: "на сколько", а не "где".let vector_x = 30.0;let vector_y = -10.0;Чтобы получить настоящее место на экране, вектор нужно прибавить к уже известной точке:
// Точка + вектор = новая точка.let point_x = center_x + vector_x;let point_y = center_y + vector_y;Это уже встречалось: center_x + direction_x * LENGTH в конце урока
«Направление» — ровно то же сложение, точка
(center_x) плюс вектор (direction_x * LENGTH), получающее точку,
где заканчивается луч. Без него направление и длина так и остались бы
подвешены в воздухе, без своего места на экране.
На самом деле это одни и те же числа
Заголовок раздела «На самом деле это одни и те же числа»Точка и вектор — оба задаются парой чисел, x и y, и с точки зрения
самих чисел это одно и то же: пара (30.0, -10.0) — и точка, и вектор
сразу, смотря как на неё посмотреть. “Точка” и “вектор” — не два
разных вида чисел, а два разных смысла для одной и той же пары.
Любую точку можно представить как вектор, который начинается в
(0, 0) и заканчивается прямо в этой точке. Тогда координаты точки —
это заодно и координаты вектора: они показывают, на сколько
сдвинуться от (0, 0), чтобы туда попасть.
Отсюда и вычитание, которое уже встречалось в уроках «Расстояние» и «Направление»:
// mouse_x, mouse_y — точка курсора.// center_x, center_y — точка центра.
// Курсор минус центр — вектор от центра к курсору.let dx = mouse_x - center_x;let dy = mouse_y - center_y;Тут мы как будто переносим начало координат из (0, 0) в центр — и
то, что от точки курсора осталось после вычитания, уже не место, а
смещение: на сколько сдвинуться от центра, чтобы попасть в курсор.
Складываем — получаем точку, вычитаем — получаем вектор.
Попробуй сам
Заголовок раздела «Попробуй сам»Серая линия — вектор, нарисованный от левого верхнего угла: это он же, но как точка. Жёлтая линия — тот же самый вектор, только прибавленный к курсору (белая точка). Подвигай мышь и поменяй вектор полями ниже — оба конца двигаются одинаково, потому что это одни и те же два числа:
use macroquad::prelude::*;
// Вектор один и тот же на каждом кадре, поэтому это константы// (как в уроке «Константы»), а не переменные внутри loop.const VECTOR_X: f32 = 150.0;const VECTOR_Y: f32 = 100.0;
#[macroquad::main("Точка плюс вектор")]async fn main() { loop { clear_background(BLACK);
// Тот же вектор, нарисованный от истинного (0, 0). draw_line(0.0, 0.0, VECTOR_X, VECTOR_Y, 4.0, GRAY); draw_circle(VECTOR_X, VECTOR_Y, 10.0, GRAY);
// Координаты курсора. let (mouse_x, mouse_y) = mouse_position();
// Белая точка — сама позиция курсора, просто ориентир. draw_circle(mouse_x, mouse_y, 6.0, WHITE);
// Тот же вектор, прибавленный к курсору: точка + вектор. draw_line(mouse_x, mouse_y, mouse_x + VECTOR_X, mouse_y + VECTOR_Y, 4.0, YELLOW); draw_circle(mouse_x + VECTOR_X, mouse_y + VECTOR_Y, 10.0, YELLOW);
next_frame().await; }}Что здесь происходит
Заголовок раздела «Что здесь происходит»vector_x,vector_y— смещение, пара чисел без собственного места на экране.center_x + vector_x,center_y + vector_y— точка плюс вектор: результат — уже настоящая точка.- Приём один и тот же для любой точки и любого вектора — не только для центра и направления на курсор, но и для позиции игрока, врага, чего угодно.
- Точка и вектор — не два разных типа значений, а два способа читать одну и ту же пару чисел: как место или как смещение.
- Серая линия в демке — вектор от
(0, 0), жёлтая — тот же вектор, прибавленный к курсору. Одинаковая длина и направление у обеих — потому что это одни и те жеVECTOR_X,VECTOR_Y. В демке они —constвнеmain, как в уроке «Константы»: значение не зависит от кадра, так что пересчитывать его внутриloopнезачем. - Если понадобится не просто прибавить вектор к точке, а растянуть его в несколько раз, саму точку не трогая, — это аккуратно разбирается в дополнительном уроке «Масштаб вокруг точки».