Московский государственный университет имени М.В.Ломоносова
Опубликован: 23.04.2007 | Доступ: свободный | Студентов: 3280 / 442 | Оценка: 4.18 / 3.71 | Длительность: 17:54:00
ISBN: 978-5-9556-0098-7
Специальности: Программист
Лекция 3:

Алгоритмы растеризации отрезков, окружностей и эллипсов

< Лекция 2 || Лекция 3: 12345 || Лекция 4 >

Алгоритм Брезенхема

Брезенхем [16] модифицировал алгоритм DDA, чтобы он работал в целых числах. Модифицируем алгоритм следующим образом:

  1. уменьшим везде e на \frac{1}{2}, чтобы сравнивать с 0 ;
  2. домножим e и \Delta e на 2a: e0 = 2b - a, \Delta e = 2b

Приходим к следующему алгоритму:

// Координаты концов отрезка - (0,0) и (a,b)
e = 2b - a;
delta_eS = 2b;
delta_eD = 2b - 2a;

x = 0; y = 0; // (x,y) - Координаты текущей точки

while(x < a)
{
      plot(x, y);

      if(e > 0)
     { // d : диагональное смещение
            x++; y++;
            e += delta_eD;
      }
      else
      { // s : горизонтальное смещение
            x++;
            e += delta_eS;
      }
}
Листинг 3.2. Алгоритм Брезенхема для отрезка

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

Алгоритм Кастла-Питвея

Этот алгоритм гораздо менее эффективен с вычислительной точки зрения, чем алгоритм Брезенхема, однако обладает красивой математической структурой. Он основан на идее, схожей с известным алгоритмом Евклида нахождения Наибольшего Общего Делителя двух натуральных чисел [19].

Будем работать со строками, кодирующими последовательность закраски (т.е. состоящими из символов s и d, определенных выше).

Определим две операции над такими строками:

  • \oplus - конкатенация строк, например

    "ssds" \oplus "sddd " = "ssdssddd "

  • \sim - "переворот" строки, например

    \sim ("ssdds") = "sddss"

// Координаты концов отрезка - (0,0) и (a,b)
y = b;
x = a - b;

m1 = "s";
m2 = "d";

while( x \ne y )
{
      if( x > y )
      {
            x = x - y;
            m2 = m1 (+)  ~ m2; 
      }
      else
      {
            y = y - x;
            m1 = m2  (+)  ~ m1; 
      }
}
Листинг 3.3. Алгоритм Кастла-Питвея

После завершения работы алгоритма m = m_2\oplus  \sim m_1 задает нужную последовательность сдвигов. Доказательство корректности работы этого алгоритма мы опустим ввиду его громоздкости.

< Лекция 2 || Лекция 3: 12345 || Лекция 4 >