Помощник
3. Отрисовка отрезков и окружностей
Для отрисовки отрезков будем пользоваться алгоритмом, который делает следующее:
Выбирает в каждом столбце ту клетку, которая ближе в прямой.
Для определения, какая точка ближе, будем делать следующее (для описания алгоритма будем считать, что dx, dy > 0 и dx > dy, где dx, dy - разница координат начала и конца отрезка. Все остальные случаи описываются симметрично):
1. Начнём с клетки начала отрезка (x_0, y_0), пройдём на 1 клетку по направлению x и рассмотрим пересечение отрезка с прямой, параллельной оси y, проходящей через середину клетки, в которую мы прошли. Заметим, что координата y у пересечения изменилась на dy/dx по сравнению с серединой начальной точки. Таким образом, для того, чтобы понять, какая из двух клеток во втором столбце ближе к отрезку, нужно сравнить dy/dx с 1/2. Далее, пройдя ещё на 1 клетку по направлению x, нужно сравнивать уже 2dy/dx с 1/2.
2. В некоторый момент случится так, что k*dy/dx станет больше 1. Тогда это будет означать, что мы достаточно продвинулись по отрезку, и теперь нужно выбирать не между точками с координатами y_0 и y_0 + 1, а между y_0 + 1 и y_0 + 2 (и соотв. сравнивать с 3/2). Можно в таком случае сравнивать k*dy/dx - 1 с 1/2.
Этот алгоритм продолжается, пока мы не окажемся в конечной точке.
3. Идея: предлагается домножить все дробные вычисления на 2*dx, тогда мы получим:
Сначала сравниваем 2*dy с dx, после 4*dy с dx ... когда k*dy становится больше, чем 2*dx, мы вычитаем 2*dx (и смещаемся на 1 по y). Таким образом, все вычисления целочисленные, и не возникает проблемы с накоплением ошибки. (Также предлагается вычесть dx, чтобы сравнение происходило с 0, но в таком случае для вычитания 2*dx нужно сравнивать с dx)
Для окружностей будем делать аналогично, только со следующей оговоркой:
Применим этот алгоритм для одной "восьмой" окружности, а остальные "восьмые" нарисуем симметрично.
На примере восьмой в первой четверти, которая ближе к оси y:
Начнём с верхней клетки и сдвинемся на 1 по оси x. Тогда для определения того, какую из двух клеток нужно отрисовать, будем рассматривать точку на середине общей стороны
(если середины (x_0 + 1; y_0) и (x_0 + 1; y_0 - 1), то серединой общей стороны будет точка (x_0 + 1; y_0 - 1/2) )
и в зависимости от того, находится ли эта точка в окружности, выбирать клетку. Если точка внутри окружности, выбираем нижнюю клетку (и после этого будем сравнивать клетки с координатами y на 1 меньше), если же снаружи, то верхнюю. Определить, находится ли точка снаружи или внутри можно по т. Пифагора (у нас должен быть дан квадрат радиуса окружности для отрисовки).
СГЛАЖИВАНИЕ
Для сглаживания будем отрисовывать не один пиксель строго чёрным цветом, а два пикселя, но в разные оттенки серого. Удобно рассматривать оттенки серого в контексте интенсивности чёрного: белый цвет (255, 255, 255) будет интенсивности 0%, черный (0, 0, 0) -- 100%, а цвета (63, 63, 63) и (127, 127, 127) -- 75% и 50% соответственно.
Тогда будем считать, что отношение интенсивностей должно быть обратно пропорционально равно отношению расстояний. К примеру, если отношение расстояний 1:3, то ближний пиксель будет закрашен с интенсивностью 75%, а дальний -- 25%.