Уроки · 52
Вращение
Давай сделаем так, чтобы вектор крутился — его направление менялось
по кругу, а длина оставалась прежней, не растягивалась и не
сжималась. Как посчитать его x и y, чтобы получилось именно
вращение, а не что попало?
Первое, что приходит в голову, — на каждом кадре понемногу прибавлять
что-то к x и к y по отдельности. Не выйдет: стоит прибавить число
к одной координате, и длина вектора сразу меняется — он растягивается
или сжимается, а не поворачивается на месте. Чтобы длину вернуть на
место, пришлось бы каждый раз заново нормировать вектор (делить на
его длину, как в уроке «Направление»).
И даже это не спасает до конца. Если вектор смотрит строго вдоль оси
x, прибавление к x вообще не меняет направление — вектор просто
становится длиннее вдоль той же прямой, а не поворачивается. Если
вместо этого прибавлять к y, направление и правда начнёт
поворачиваться — но до 90° так и не дойдёт никогда: с каждым шагом
угол приближается к 90° всё ближе, а чтобы дойти до него ровно,
нужно было бы прибавить бесконечность, а бесконечность в коде не
отрисуешь.
Должно быть другое правило — такое, что сразу даёт нужные x и y
для вращения. И оно есть: у чисел в Rust уже готовы функции .cos()
и .sin() (те самые синус и косинус, знакомые ещё со школы) — берём
и вызываем:
let x = angle.cos();let y = angle.sin();Если angle — это угол в радианах (не привычные градусы), cos
и sin дают ровно то, что нужно: x и y точки на окружности
радиусом 1, повёрнутой на этот угол. Длина вектора всегда останется
1, какой угол ни возьми. Подробнее про радианы и про то, что здесь
вообще происходит геометрически, можно почитать в дополнительных
уроках «Синус и косинус» и
«Радианы» — для самого вращения достаточно
знать, что cos/sin работают именно так.
А дальше всё просто: если на каждом кадре прибавлять к angle одно и
то же число, вектор будет равномерно вращаться — угол понемногу
растёт, а cos/sin каждый раз дают чуть-чуть другое направление на
той же самой окружности.
Как уже говорилось в уроке «Координаты», ось y
на экране растёт вниз, а не вверх, как в школьной математике —
поэтому рост angle через cos/sin крутит на экране по часовой
стрелке, а не против, как было бы на бумаге.
Попробуй сам
Заголовок раздела «Попробуй сам»Вектор всегда начинается в нуле — его направление это (angle.cos(), angle.sin()). Кнопка ниже каждый кадр
увеличивает angle, и вектор плавно крутится по кругу.
Что здесь происходит
Заголовок раздела «Что здесь происходит»(angle.cos(), angle.sin())— направление вектора:xиyточки на окружности радиусом 1, повёрнутой наangle.- Если
angleрастёт на одно и то же число каждый кадр, вектор равномерно вращается — длина не меняется, меняется только направление. - Из-за перевёрнутой оси
yвращение на экране идёт по часовой стрелке, а не против. - Этот вектор всегда начинается в нуле. В следующем уроке, «Спутник», с его помощью сделаем кружок, который вращается вокруг другого.