Алгоритм DDA (Digital Differential Analyzer)

Строит 8-связную линию


e0=< 1 ; De=< 1

 

P1=(1,0) ; P2=(1,1)

 

В начальный момент

x=0;

y=0;

e=e0;


Рис. 5. Алгоритм DDA.

 

В силу подобия треугольников, для того чтобы определить, какая из точек (P1 или P2) ближе, достаточно сравнить расстояния от точки пересечения P до P1 и P2, что равносильно сравнению e с 1/2.

 


Алгоритм:

 

while(x £ a)

{

plot(x,y);

 

if (e>=1/2)

{

// d : диагональное смещение

x++; y++;

e+=De-1 ; // т.к. произошло смещение по y на 1 вверх

}

else

{

// s : горизонтальное смещение

x++;

e+=De;

}

}

 

Недостаток алгоритма:

Работает с числами с плавающей точкой.

 

Модифицируем наш алгоритм так, чтобы он работал с целыми числами:

1) В начале e0=De -1/2. (чтобы сравнивать с 0);

2) домножим e0 и De на 2a :

De=2b , e0=2b-a .

 

Кроме этого, вынося общую для обоих случаев часть из else,приходим к следующему алгоритму, называемому

 

Алгоритм Брезенхема [Bresenham, 1965]

 

while(x £ a)

{

plot (x,y);

 

if (e>=0)

{

// диагональное смещение

y++;

e-=2a ; // раньше это соответствовало e-=1 (смещение по y на 1 вверх)

}

// часть, общая для диагонального и горизонтального смещений

x++;

e+= De ;

}

 

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

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

 

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

 

Алгоритм Castle-Pitteway [Castle-Pitteway, 1987]

РисуемAB : A (0,0) -> B (x,y)

 

s и d понимаются в описанном выше смысле

m1 и m2 - строки

 

Å - конкатенация строк (например "ssds" Å "sddd"="ssdssddd" )

~ - "переворот" строки (например ~ ("ssdds")="sddss" )

 

b=y;

a=x-y;

m1="s";

m2="d";

 

while (a ¹ b)

{

a= a - b;

m2=m1 Å 2 ;

}

else

{

b=b - a;

m1=m2 Å 1 ;

}

 

После завершения работы алгоритма m= m2 Å 1 задает нужную последовательность сдвигов.

 

Доказательство корректности работы этого алгоритма мы опустим ввиду его громоздкости.