Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
382
Добавлен:
18.03.2016
Размер:
4.2 Mб
Скачать

120

Рис. 6.4. Аппроксимация площади пикселя

Сформулируем алгоритм Брезенхейма, учитывающий площадь части пикселя для устранения ступенчатости. Если к ошибке в исходном алгоритме Брезенхейма добавить величину w = 1 - m, т.е. ввести преобразование e' = e + w, то 0≤e'≤1. Теперь ошибка е' - это мера площади той части пикселя, которая находится внутри многоугольника, т. е. уi+m/2. В связи с этими модификациями начальное значение ошибки равно 1/2, поэтому для первого пикселя алгоритм, приводившийся на первом рисунке, всегда будет выдавать значение интенсивности, равное половине максимальной. Более реалистичное значение для первого пикселя дает перемещение оператора активирования на другое место. Более того, можно получить непосредственно значение интенсивности, а не десятичную дробь от ее максимума с помощью умножения на максимальное число доступных уровней интенсивности I следующих величин: тангенса угла наклона (m), весового коэффициента (w) и ошибки е'.

6.1.3. Алгоритм Ву для растеризации отрезка с антиалиасингом

Ранее были рассмотрены алгоритмы Брезенхейма генерации развертки отрезка. Его недостатком является то, что он рисует отрезки с неровными, резкими краями. Для преодоления этого недостатка Wu Xiaolin создал алгоритм, рисующий «сглаженный» отрезок. Алгоритм Ву является одним из методов антиалиасинга.

Предыдущие алгоритмы рисовали отрезки одним цветом, этот алгоритм закрашивает разные участки отрезка в разные цвета и за счет этого «сглаживает» неровности.

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

121

прерывно. За счет этого можно обеспечивать плавную анимацию при рисовании движущихся изображений.

Основная идея алгоритма – работа с парами пикселей, между центрами которых проходит отрезок. Здесь пиксели – это квадраты со стороной 1 и центрами, расположенными в узлах целочисленной решетки. Когда мы говорим "пиксель с координатами (x,y)", то имеем в виду, что его центр расположен в этой точке.

На рис.6.5 показано, как выбираются из множества пикселей пары. В данном случае прямая лежит ближе к оси OX, чем к OY, поэтому пары состоят из соседних по вертикали элементов. Если бы прямая была ближе к оси OY, то выбирались бы пары из соседних по горизонтали.

Рис.6.5. Построение сглаженного отрезка

Суммарная яркость выделенных пар пикселей равна единице. Пропорция, в которой эта яркость распределяется внутри пары, зависит от близости отрезка к центру пикселя.

При всей своей простоте такой метод быстр и позволяет строить очень качественно сглаженные отрезки.

6.2. Алгоритм Брезенхейма построения окружности

Из геометрии известно, что окружность с центром в точке (xc, yc) и радиусом r, задается параметрически с помощью системы уравнений:

x = xc + r cosα,

где α [0;2π).

 

y = yc + r sinα,

 

Отсюда несложно получить алгоритм генерации окружности:

1.Полагаем А=0.

2.Если А больше либо равно 2π, то окружность нарисована.

3.Вычислим x=Trunc(xc+r*cos(A)), y=Trunc(yc+r*sin(A)).

4.Screen[x,y]=Color.

5.Увеличим A на d (A:=A+d) и перейдем к шагу 2.

122

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

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

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

1.Полагаем А=0.

2.Если А больше либо равно π, то окружность нарисована.

3.Вычислим x=Trunc(r*cos(A)), y=Trunc(r*sin(A)).

4.Screen[xc+x,yc+y]=Color.

5.Screen[xc+x,yc-y]=Color.

6.Увеличим A на d (A:=A+d) и перейдем к шагу 2. Рассмотренный вариант работает немного быстрее. Однако вы-

делим две простые идеи, используемые в этом алгоритме, которые будут полезны в дальнейшем. Первая заключается в том, что на шаге 3 мы вычисляем координаты (x,y) точки на окружности радиуса r с центром в начале координат, а на шаге 4 просто осуществляем сдвиг. Вторая заключается в том, что благодаря симметрии справедливо утверждение: если точка (x,y) лежит на окружности с центром в точке (0,0), то и точка (x,-y) так же лежит на этой окружности. Последнее утверждение можно развить, а именно: если точка (x,y) лежит на окружности с центром в точке (0,0), то и точки (x,-y);(-x,-y);(- x,y);(y,x),(y,-x);(-y,-x);(-y,x) также лежат на этой окружности. Для про-

верки можно использовать следующее уравнение, задающее окруж-

ность: x2+y2=r2.

123

Итак, вся подготовительная работа выполнена. Пусть есть функция NextPoint(x,y,r), которая выдает точки, лежащие на окружности с центром в начале координат и радиусом r, при этом пусть это будут точки из выделенного сектора рис.6.6.

y 45o

x

O

Рис. 6.6. Разбиение окружности на части

Тогда наш алгоритм можно будет записать в виде:

1.y:=r; x:=0;

2.Screen[x+xc,y+yc]:=Color;

3.Screen[x+xc,-y+yc]:=Color;

4.Screen[-x+xc,y+yc]:=Color;

5.Screen[-x+xc,-y+yc]:=Color;

6.Screen[y+xc,x+yc]:=Color;

7.Screen[y+xc,-x+yc]:=Color;

8.Screen[-y+xc,x+yc]:=Color;

9.Screen[-y+xc,-x+yc]:=Color;

10.NextPoint(x,y,r);

11.Если получили новую точку, то на шаг 2, иначе окружность нарисована.

Рассмотрим, как работает функция NextPoint. Нетрудно заметить, что координата x в выделенном секторе (рис. 6.5) увеличивается на единицу на каждом шаге (для проверки можно, например, подсчитать производную функции y=f(x), задающей часть окружности – она будет больше 1). Так же ясно, что координата y либо уменьшается на единицу, либо остается без изменений. Итак, осталось выбрать, куда переходить из точки (xi,yi): либо в точку (xi+1,yi), либо в точку (xi+1,yi-1). Для того, чтобы осуществить выбор, рассмотрим две невязки:

d1i = (xi +1)2 + yi2 r2 ,

d2i = (xi +1)2 +( yi 1)2 r2.

124

Также будем следить за их суммой:

d i = d1i + d2i .

Рассмотрим несколько вариантов расположения "вещественной" окружности относительно "целых" точек, показанных на рис. 6.7.

 

2

1

(x ,y )

1 (xi+1,yi)

 

i i

 

 

3

4

2 (xi+1,yi-1)

5

Рис. 6.7. Варианты расположения линии окружности

Понятно, что в случаях 1 и 2 надо "зажигать" точку 1, а в случаях 4 и 5 – точку 2, случай 3 требует более тщательного рассмотрения. Попробуем формализовать все пять случаев при помощи введенных

параметров di; di1; di2:

Случай 1. di1 < 0, di2 < 0, di < 0. Случай 2. di1= 0, di2 < 0, di < 0.

Случай 3. di1 > 0, di2 < 0, получаем два варианта для di:

Случай 3.1. |di1| < |di2| di < 0. Случай 3.2. |di1| > |di2| di > 0.

Случай 4. di1 > 0, di2=0, di > 0.

Случай 5. di1 > 0, di2 > 0, di > 0.

Подводя итог, имеем: в случае, если di < 0, надо активировать точку (xi+1,yi), а в случае, если di > 0, надо активировать точку (xi+1,yi-1). Осталось получить выражение для di:

di = di + di

= (x +1)2

+ y2

r2 +(x +1)2

+( y 1)2

r2

=

 

1 2

i

i

i

i

 

 

= 2x2

+ 2y2

+ 4x 2y +3 2r2.

 

 

 

i

i

i

i

 

 

 

 

Теперь получим выражение di+1 через di, избавившись от операции возведения в квадрат. Пусть вначале yi+1=yi, тогда

d i+1 = 2xi2+1 + 2yi2+1 + 4xi+1 2yi+1 +3 2r2 = d i + 4xi + 6.

Теперь пусть yi+1=yi-1, тогда

d i+1 = 2xi2+1 + 2yi2+1 + 4xi+1 2yi+1 +3 2r2 = d i + 4(xi yi ) +10.

Соседние файлы в папке Брундасов. Компьютерная графика. Лекции