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

Заполнение многоугольников и областей

< Лекция 5 || Лекция 6: 1234 || Лекция 7 >
Аннотация: Введение. Растеризация многоугольников: алгоритм со списком реберных точек, алгоритм со списком активных ребер, алгоритм с операцией XOR, исключительные случаи, алгоритм с операцией XOR с перегородкой. Заполнение с затравкой

6.1. Введение

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

Будут рассмотрены два случая. В первом требуется нарисовать на растре многоугольник, заданный своими вершинами ( растеризация многоугольника ). Во втором, более общем случае мы будем считать, что растровая область задана цветом своей границы и точкой (пикселем) внутри области. Этот пиксель называется затравочным, а сам метод называется заполнением с затравкой.

6.2. Растеризация многоугольников

Пусть задан многоугольник P1P2 . . . PNP1 и требуется растеризовать его вместе с внутренними точками. Будем считать, что процедура отсечения ( "Отсечение отрезков и многоугольников" ) при необходимости была уже произведена и многоугольник целиком помещается в растровом окне. Для удобства каждое ребро многоугольника будем задавать координатами (x1, y1) и (x2, y2) его концов, так, что y_2 \ge y_1. Условимся также отсчитывать на экране координату x слева направо, а y - сверху вниз (таким образом, точка (x1, y1) будет верхним концом ребра, а (x2, y2) - нижним). Большинство алгоритмов заполнения основано на том факте, что любое горизонтальное сечение контура многоугольника состоит из четного числа точек. Это утверждение неверно в двух случаях (см. рис. 6.1):

  • когда секущая прямая содержит горизонтальное ребро;
  • когда она содержит вершину, а оба смежных ребра лежат выше (ниже) ее.
Исключительные случаи.

Рис. 6.1. Исключительные случаи.

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

Алгоритм со списком реберных точек

Этот алгоритм состоит из трех основных этапов.

На первом этапе растеризуются все негоризонтальные ребра многоугольника. Все точки помещаются в списки. Для каждой координаты ymin, y2 . . . ymax сопоставим список x-координат всех пикселей, закрашенных при растеризации ребер, которые находятся на горизонтали y (здесь ymin и ymax - минимальная и максимальная y-координаты пикселей в растровом изображении многоугольника). Формально процедура описывается так:

Пример сечений многоугольника.

Рис. 6.2. Пример сечений многоугольника.
foreach( ребро (x1, y1) - (x2, y2) in МножествоРебер )
{
      y = ceil(y1); // Округление до большего
      dx = (x2 - x1)/(y2 - y1);
      x = x1 + dx*(y - y1);

      while(y <= y2)
      {
            PutToList(x, y); // поместить x в список,
                                  // соответствующий данному y
            y++;
            x += dx;
      }
}
Листинг 6.1. Растеризация ребер

На втором этапе для каждого y списки упорядочиваются по возрастанию. После этого для многоугольника, изображенного на рис. 6.2, списки будут выглядеть следующим образом:

ymin x1, x2
ymin + 1 x'1, x'2
. . . . . .
y0 x1 >>, x2 >>, x3 >>, x4 >>
. . . . . .
ymax

На третьем этапе в каждой строке заполняются все отрезки вида [x2i-1, x2i].

< Лекция 5 || Лекция 6: 1234 || Лекция 7 >