Уроки · 60
Угол от 0 до 360°
В уроке «Угол вектора» atan2 вернул угол от −π
до π (в градусах — от −180° до 180°). Работать с таким диапазоном
не всегда удобно: удобнее, когда угол всегда от 0 до 2π (в
градусах — от 0° до 360°) — тогда он всегда один и тот же знак, без
разбора случаев по всему коду.
rem_euclid — остаток от деления
Заголовок раздела «rem_euclid — остаток от деления»Остаток от деления — это то, что осталось лишним, если разделить одно
число на другое нацело. Раздели 10 на 3 — поместится три целых тройки
(3 × 3 = 9), а один останется лишним: это и есть остаток, 1.
С отрицательными числами rem_euclid даёт остаток, который никогда
не бывает отрицательным. Раздели -10 на 3 — поместится уже не три
тройки, а четыре, только в минус (3 × -4 = -12), и тогда до -10 не
хватает, а наоборот — перебор на 2. Вот этот 2 и есть остаток:
3 × -4 + 2 = -10.
С углом работает та же арифметика, просто делитель — не 3, а один
полный оборот. -90, поделённое так на 360, даёт остаток 270
(360 × -1 + 270 = -90) — то есть ровно то же самое направление, но
уже в привычном диапазоне. В Rust эта операция уже готова, называется
.rem_euclid():
use std::f32::consts::PI;
let normalized = angle.rem_euclid(2.0 * PI);Один вызов — и normalized всегда лежит в 0..2π, какой бы угол ни
подставили: свежий результат atan2, как в уроке «Угол
вектора», или угол, который растёт каждый кадр и
никогда не сбрасывается, как в уроках «Вращение» и
«Спутник» — и за много кадров вполне мог накрутить
не один оборот. rem_euclid работает одинаково в любом из этих
случаев, разбирать их по отдельности не нужно.
То же самое и в градусах, без радианов:
let normalized_degrees = angle_degrees.rem_euclid(360.0);Попробуй сам
Заголовок раздела «Попробуй сам»raw = 450° → rem_euclid: 90°
Двигай ползунок — raw изображает угол, который успел
накопиться за много кадров и мог обернуться вокруг оси не один раз.
Стрелка на картинке всегда стоит под результатом rem_euclid, при любом значении raw.
Что здесь происходит
Заголовок раздела «Что здесь происходит»angle.rem_euclid(2.0 * PI)— остаток от деленияangleна один полный оборот,2π. Результат всегда от0до2π, независимо от того, сколько оборотов было в исходном угле и в какую сторону.- Для отрицательных чисел
rem_euclidберёт на одно деление больше в минус, лишь бы остаток не оказался отрицательным — как-90, поделённое на360, даёт остаток270, а не-90. std::f32::consts::PI— готовая константа для числаπ, чтобы не вписывать3.14159...в код руками.- В демке
raw— это угол, который мог накопиться за много кадров и обернуться вокруг оси не один раз. Стрелка всегда стоит подrem_euclid-результатом, при любом значенииraw.