Перейти к содержимому

Уроки · 62

Дуга

Иногда нужна не вся окружность, а только её кусок — дуга. В macroquad для этого уже есть готовая функция, draw_arc, но, в отличие от знакомых draw_circle и draw_circle_lines, у неё сразу семь параметров, и расставлены они не так, как можно было бы ожидать. Разберём каждый по отдельности:

draw_arc(x, y, sides, radius, rotation, thickness, arc, color);
  • x, y — центр окружности, из которой берём кусок, — то же самое, что и у draw_circle.
  • sides — на сколько прямых отрезков разбить кривую, та же идея, что и в уроке «Многоугольники». Только здесь это не число отрезков самой дуги, а число отрезков, на которое разбили бы полную окружность такого же радиуса — для короткой дуги функция сама возьмёт от этого числа только нужную долю.
  • radius — радиус, тот же самый, что и у draw_circle.
  • rotation — угол, под которым дуга начинается. Отсчитывается так же, как в уроке «Вращение» — по часовой стрелке на экране, раз ось y перевёрнута (как в уроке «Координаты»). И вот тут отличие: rotation — в градусах, а не в радианах, хотя cos/sin из прошлых уроков работали строго с радианами. Переводить самому не нужно — функция ждёт готовые градусы.
  • thickness — толщина дуги, та же идея, что и у draw_line или draw_circle_lines.
  • arc — сколько градусов дуги рисовать, начиная от rotation, по часовой стрелке. Тоже в градусах.
  • color — цвет, как обычно.

Параметры стоит запоминать по именам, а не по порядку: thickness здесь идёт перед arc, хотя у draw_circle_lines толщина сразу после радиуса, — сигнатуры этих функций устроены по-разному.

Серый контур — ориентир, полная окружность того же радиуса. Жёлтая дуга начинается под углом rotation и тянется на arc градусов по часовой стрелке. Подвигай оба поля:

src/main.rs
use macroquad::prelude::*;
// Толщина дуги и то, на сколько отрезков приближаем полную окружность
// такого же радиуса, — фиксированные, в демке не меняются.
const THICKNESS: f32 = 16.0;
const SIDES: u8 = 60;
#[macroquad::main("Дуга")]
async fn main() {
loop {
clear_background(BLACK);
let center_x = screen_width() / 2.0;
let center_y = screen_height() / 2.0;
let radius = 200.0;
// Угол, с которого дуга начинается, — в градусах.
let rotation = 0.0;
// Сколько градусов дуги рисуем, начиная от rotation.
let arc = 90.0;
// Полная окружность — только для ориентира, чтобы видно было,
// частью какого круга является дуга.
draw_circle_lines(center_x, center_y, radius, 2.0, LIGHTGRAY);
// Сама дуга.
draw_arc(center_x, center_y, SIDES, radius, rotation, THICKNESS, arc, YELLOW);
next_frame().await;
}
}
  • Серый контур — полная окружность того же радиуса, нарисована только для ориентира и ни на что не влияет.
  • rotation — угол, с которого дуга начинается.
  • arc — сколько градусов дуги рисуется дальше, по часовой стрелке от rotation.
  • SIDES и THICKNESS — константы, в демке не меняются: число отрезков и толщина дуги заданы один раз и фиксированы, в отличие от rotation/arc, которые управляются полями.