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

Компьютерная графика.

Алгоритм вывода окружности.

Рисунок 22: Растеризация окружности.

Для вывода окружности можно использовать соотношение между координатами X и Y для точек круга X2 + Y2 = R2 и построить алгоритм прямого вычисления координат. Однако тогда необходимо вычислять квадратный корень, а это выполняется медленно.

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

Окружность строится так же на принципе центральной точки. Для начала необходимо поставить четыре точки на пересечении осей координат и окружности. Далее воспользуемся свойством симметричности окружности, за начальные значения возьмем x = 0, y = r , а за критерий выхода из цикла x <= y. Это означает, как только построим восьмую часть окружности цикл завершится. Так же на каждой итерации цикла мы будем устанавливать не одну, а сразу восемь симметрично расположенных точек.

Рисунок 23: Алгоритм построения окружности.

-38-

Компьютерная графика.

Теперь необходимо рассмотреть принцип выбора закрашиваемого пикселя. Для этого нам необходимо уравнение окружности:

x2 + y2=r2 ,

получаем функцию:

f(x , y )=x2 + y2r2 .

Вфункцию f(x,y) мы можем подставить координаты любой точки и проверить, находится точка внутри окружности или снаружи. Отметим, считается что центр окружности находится в центре координат (cx = 0, cy = 0).

{f (x , y)>0 f (x , y )=0 f (x , y)<0

точка( x , y)вне окружности , точка( x , y)на окружности , точка( x , y)внутри окружности.

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

Рисунок 24: Алгоритм Брезенхэма.

Алгоритм на языке C/C++:

int x = 0; float y = r; float f;

SetPixel(cx, cy + r);

SetPixel(cx, cy - r);

SetPixel(cx + r, cy);

SetPixel(cx - r, cy);

while(x <= y)

{

f = (x + 1) * (x + 1) + (y - 0.5) * (y - 0.5) - r * r;

if(f > 0)

{

y = y - 1;

}

x = x + 1;

-39-

Компьютерная графика.

SetPixel(cx + x, cy + y);

SetPixel(cx + x, cy - y);

SetPixel(cx - x, cy + y);

SetPixel(cx - x, cy - y);

SetPixel(cx + y, cy + x);

SetPixel(cx + y, cy — x);

}

Данный алгоритм наделен некоторыми недостатками, а точнее вещественной арифметикой и вычислениями на каждой итерации цикла. Для избавления от этих недостатков необходимо рассмотреть две итерации цикла и внести некоторые изменения в алгоритм.

На 1-й итерации цикла мы рассматриваем точку M(x+1, y-1/2), на следующей итерации нам необходимо рассматривать точку ME(x+2, y-1/2), либо точку MSE(x+2, y-3/2). Запишем значения функции f(x,y) на этих итерациях:

f(M )= f (x+1, y1 /2)=( x+1)2+( y1 /2)2r2=x2+2x+1+ y2y+1/ 4r2 ,

f(M E )= f ( x+2, y1 /2)=( x+2)2+( y1/ 2)2r2=x2+4x+4 + y2y+1/ 4r2= f ( M )+2x+3,

f(M SE )= f ( x+2, y3/2 )=(x+2)2+( y3/2 )2r2=x2 +4x+4+ y23y+9 /4r2= f (M )+2x2y+5.

Рисунок 25: Алгоритм Брезенхэма.

Приращения найдены, осталось найти значение функции в самой первой точке

(x1,y1):

f (M 0)= f (1, r1 /2)=12 +(r1/2)2r 2=1+r2r1 /4r2 =5/4r.

Если посмотреть внимательнее на приращения, то можно заметить что приращения целочисленные в обоих случаях (2x + 3) и (2x – 2y + 5), а также начальное значение f(M0) – это целое число сдвинутое на одну четверть. Это означает, что мы можем отказаться от ¼ в начальных значениях f(M0), т.к. это никак не повлияет на сравнение с нулем:

f (M 0)=1r.

-40-

Компьютерная графика.

Реализуем алгоритм:

int x = 0; int y = r; int f = 1 - r;

SetPixel(cx, cy + r);

SetPixel(cx, cy - r);

SetPixel(cx + r, cy);

SetPixel(cx - r, cy);

while(x <= y)

{

if(f > 0)

{

y = y - 1;

f = f + 2*(x - y) + 5;

}

else

{

f = f + 2*x + 3;

}

x = x + 1;

SetPixel(cx + x, cy + y); SetPixel(cx + x, cy - y); SetPixel(cx - x, cy + y); SetPixel(cx - x, cy - y); SetPixel(cx + y, cy + x); SetPixel(cx + y, cy - x); SetPixel(cx - y, cy + x); SetPixel(cx - y, cy - x);

}

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

Рассмотрим приращения по каждому направлению E и SE (incrE = 2*x + 3, incrSE = 2*(x – y) + 5):

если выбрана точка E, то значение x увеличивается на еденицу (incrE = incrE + 2, incrSE = incrSE + 2);

если выбрана точка SE, то значение x увеличивается на еденицу и значение y

уменьшается на 1 (incrE = incrE + 2, incrSE = incrSE + 4). Начальные значения incrE = 3, incrSE = 5 — 2*r.

Алгоритм с оптимизацией:

int x = 0; int y = r; int f = 1 - r; int incrE = 3;

int incrSE = 5 - 2 * r;

-41-

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]