Алгоритм среднего круга - Википедия - Midpoint circle algorithm

Растеризация круга радиуса 23 с помощью алгоритма средней точки Брезенхема. Только зеленый октант фактически вычисляется, он просто отражается восемь раз, чтобы сформировать остальные семь октантов.
Сто пятьдесят концентрические круги нарисованный с помощью алгоритма окружности средней точки. Слева все круги нарисованы черным; справа красный, черный и синий используются вместе, чтобы продемонстрировать концентричность кругов.
Круг радиуса 23, нарисованный алгоритмом Брезенхема

В компьютерная графика, то алгоритм средней точки круга алгоритм, используемый для определения точек, необходимых для растеризация а круг. Bresenham Алгоритм окружности является производным от алгоритма окружности средней точки.[нужна цитата ] Алгоритм можно обобщить на конические секции.[1]

Алгоритм связан с работой Pitteway.[2] и Ван Акен.[3]

Резюме

Этот алгоритм рисует все восемь октантов одновременно, начиная с каждого кардинального направления (0 °, 90 °, 180 °, 270 °) и расширяет оба пути, чтобы достичь ближайшего кратного 45 ° (45 °, 135 °, 225 °, 315 °). ). Он может определить, где остановиться, потому что, когда y = x, он достигает 45 °. Причина использования этих углов показана на рисунке выше: по мере увеличения y не пропускается и не повторяется какое-либо значение y до достижения 45 °. Таким образом, во время цикла while y увеличивается на 1 на каждой итерации, а x уменьшается на 1 при случае, никогда не превышая 1 за одну итерацию. Это изменяется при 45 °, потому что это точка, где касательная поднимается = проходит. Тогда как подъем> беги до и подъем <бег после.

Вторая часть проблемы, детерминант, намного сложнее. Это определяет, когда уменьшать x. Обычно это происходит после рисования пикселей на каждой итерации, потому что он никогда не опускается ниже радиуса первого пикселя. Поскольку в непрерывной функции функция для сферы является функцией для круга с радиусом, зависящим от z (или какой-либо третьей переменной), само собой разумеется, что алгоритм для дискретной (воксельной) сферы также будет полагаться на этот алгоритм круга средней точки. Но при взгляде на сферу целочисленный радиус некоторых соседних кругов одинаков, но не ожидается, что он будет иметь такой же точный круг, прилегающий к самому себе в том же полушарии. Вместо этого для круга того же радиуса требуется другой определитель, чтобы кривая могла входить немного ближе к центру или расширяться дальше.

Алгоритм

Цель алгоритма - аппроксимировать кривую с помощью пикселей; в условия непрофессионала каждый пиксель должен находиться примерно на одинаковом расстоянии от центра. На каждом шаге путь расширяется путем выбора соседнего пикселя, который удовлетворяет но максимизирует . Поскольку пиксели-кандидаты являются смежными, арифметика для вычисления последнего выражения упрощается, требуя только битовых сдвигов и сложений. Но можно сделать упрощение, чтобы понять битовый сдвиг. Имейте в виду, что сдвиг двоичного числа влево - это то же самое, что умножение на 2. Следовательно, сдвиг радиуса влево дает только диаметр который определяется как радиус, умноженный на два.

Этот алгоритм начинается с круг уравнение. Для простоты предположим, что центр круга находится в . Рассмотрим сначала только первый октант и нарисуем кривую, которая начинается в точке и идет против часовой стрелки, достигая угла 45.

В быстрый направление здесь ( базисный вектор с большим увеличением значения) - направление. Алгоритм всегда делает шаг в положительную сторону. направлении (вверх) и иногда делает шаг в медленный направление (отрицательное направление).

Из уравнения окружности получается преобразованное уравнение , куда вычисляется только один раз при инициализации.

Пусть точки на окружности представляют собой последовательность координат вектора до точки (в обычном базисе). Очки нумеруются в соответствии с порядком розыгрыша, при этом присвоено первой точке .

Для каждой точки выполняется следующее:

Это можно изменить так:

И то же самое для следующего пункта:

Поскольку для первого октанта следующая точка всегда будет как минимум на 1 пиксель выше последней (но также не более чем на 1 пиксель выше для сохранения непрерывности), верно, что:

Итак, переработайте уравнение следующей точки в рекурсивное, подставив :

Из-за непрерывности круга и из-за того, что максимумы по обеим осям одинаковы, очевидно, что он не будет пропускать x точек по мере продвижения в последовательности. Обычно он остается на той же координате x, а иногда увеличивается на единицу.

Полученная координата затем переводится путем добавления координат средней точки. Эти частые добавления целых чисел не ограничивают спектакль много, поскольку эти вычисления квадратного (корня) могут быть по очереди сохранены во внутреннем цикле. Опять же, ноль в уравнении преобразованного круга заменяется членом ошибки.

Инициализация члена ошибки получается из смещения на 1/2 пикселя в начале. До пересечения с перпендикулярной линией это приводит к накопленному значению в термине ошибки, так что это значение используется для инициализации.

Частые вычисления квадраты в уравнении круга, тригонометрический выражения и квадратные корни снова можно избежать, разложив все на отдельные шаги и используя рекурсивное вычисление квадратичный термины из предыдущих итераций.

Вариант с арифметикой на основе целых чисел

Так же, как с Линейный алгоритм Брезенхема, этот алгоритм можно оптимизировать для целочисленной математики. Из-за симметрии, если можно найти алгоритм, который вычисляет пиксели только для одного октанта, пиксели могут быть отражены, чтобы получить весь круг.

Мы начинаем с определения ошибки радиуса как разницы между точным представлением круга и центральной точкой каждого пикселя (или любой другой произвольной математической точкой на пикселе, если она согласована для всех пикселей). Для любого пикселя с центром в , ошибка радиуса определяется как:

Для наглядности эта формула для круга выводится в начале координат, но алгоритм может быть изменен для любого местоположения. Полезно начать с точки на положительной оси X. Поскольку радиус будет целым числом пикселей, очевидно, что ошибка радиуса будет равна нулю:

Поскольку он начинается в первом положительном октанте против часовой стрелки, он будет двигаться в направлении наибольшего путешествовать, направление Y, поэтому ясно, что . Кроме того, поскольку это касается только этого октанта, значения X имеют только 2 варианта: оставаться такими же, как на предыдущей итерации, или уменьшаться на 1. Может быть создана переменная решения, которая определяет, верно ли следующее:

Если это неравенство выполняется, то построить график ; если нет, то сюжет . Итак, как определить, выполняется ли это неравенство? Начнем с определения ошибки радиуса:

Функция абсолютного значения не помогает, поэтому возведите обе стороны в квадрат, поскольку квадрат всегда положителен:

Поскольку x> 0, член , поэтому при делении получается:

Таким образом, критерий принятия решения меняется от использования операций с плавающей запятой к простому целочисленному сложению, вычитанию и сдвигу битов (для операций умножения на 2). Если , затем уменьшите значение X. Если , затем оставьте то же значение X. Опять же, отражая эти точки во всех октантах, получается полный круг.

Отрисовка неполных октантов

Приведенные выше реализации всегда рисуют только полные октанты или круги. Чтобы нарисовать только определенный дуга под углом под углом , алгоритм должен сначала вычислить и координаты этих конечных точек, где необходимо прибегать к тригонометрическим вычислениям или вычислениям квадратного корня (см. Методы вычисления квадратных корней ). Затем алгоритм Брезенхема проходит по полному октанту или кругу и устанавливает пиксели, только если они попадают в желаемый интервал. После завершения этой дуги алгоритм можно преждевременно завершить.

Если углы заданы как склоны, то тригонометрия или квадратные корни не нужны: просто проверьте, что находится между желаемыми спусками.

Обобщения

Также можно использовать ту же концепцию для растеризации парабола, эллипс, или любой другой двумерный изгиб.[4]

Рекомендации

  1. ^ Дональд Хирн; М. Полин Бейкер (1994). Компьютерная графика. Прентис-Холл. ISBN  978-0-13-161530-4.
  2. ^ Питтуэй, M.L.V. "Алгоритм рисования эллипсов или гипербол на цифровом плоттере ", Computer J., 10 (3) ноября 1967 г., стр. 282-289.
  3. ^ Ван Акен, Дж. Р. "Эффективный алгоритм рисования эллипса ", CG&A, 4 (9), сентябрь 1984 г., стр. 24-35.
  4. ^ Зингл, Алоис (декабрь 2014 г.). «Красота алгоритма Брезенхема: простая реализация для построения линий, окружностей, эллипсов и кривых Безье». easy.Filter. Алоис Зингл. Получено 16 февраля 2017.

внешняя ссылка