Заполнение многоугольников. Алгоритмы заполнения по ребрам, с перегородкой, со списком ребер и флагом.



 

Алгоритм по рёбрам
фон = -закраска; закраска = -фон. Для каждой сканирующей строки, пересекающей ребро многоугольника, дополнить все пиксели, лежащие правее точки пересечения. Недостаток – каждый пиксель может перекрашиваться много раз.

Алгоритм с перегородкой
Для сокращения числа обрабатываемых пикселов используется ″перегородка". Рекомендуется проводить перегородку через одну из вершин многоугольника.

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

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

Алгоритм с флагом

  1. Обработка ребер многоугольника, ограничивающего заполняемую область. Также, как в предыдущих алгоритмах, считается, что строки сканирования проходят через центр строк пикселов, то есть через середину интервала y. После определения пересечений вычисляем самый левый пиксел, расположенный правее точки пересечения, у которого абсцисса x больше абсциссы точки пересечения.
  2. Заполнение области. Для каждой строки сканирования, имеющей точки пересечения с многоугольником, ограничивающим область, выполняется следующая последовательность действий:
    а) f=0, (f-промежуточная переменная (флаг), показывающая расположение очередного пиксела: fl=0 - пиксел лежит вне области заполнения, fl=1 - пиксел лежит внутри заполняемой области);
    x=xl (xl - левая граница);
    б) пока (x<=xr ) (xr - правая граница) выполнить следующие действия:
    * если пиксел (x,y) имеет граничное значение , то проинвертировать значение переменной f (f=0, если было f=1; f=1, если было f=0);
    * если f=1, то присвоить пикселу (x,y) цвет многоугольника, в противном случае, присвоить пикселу (x,y) цвет фона;
    x=x+1.
    в) переход к следующей сканирующей строке y=y+1.

Алгоритм заполнения с затравкой, простой алгоритм заполнения с затравкой.

 

Необходимо:
Задать область и координаты точки внутри области. Рассматриваются пиксели, соседние с данным. Используется стек.

Простой алогритм

  1. Задание исходных данных
  2. Поместить затравочный пиксель в стек
  3. Пока стек не пуст
    1. Извлечь (xy) из стека
    2. Цвет(xy)≠Закраска -> Цвет(xy):=Закраска
    3. Анализ 4 соседних пикселей. Цвет≠Закраска и Цвет≠Граница -> пиксель в стек

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

 

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

pix = QPixmap()

 

paint = QPainter()

paint.begin(win.image)

 

stack = []

 

edge = QColor(0, 0, 255).rgb()

fill = QColor(0, 0, 0).rgb()

#paint.setPen(QPen(fill))

 

z = QPointF(win.p_x.value(), win.p_y.value())

stack.append(z)

 

# пока стек не пуст

 

while stack:

# извлечение пикселя (х,у) из стека

p = stack.pop()

x = p.x()

y = p.y()

# tx = x, запоминаем абсицссу

xt = p.x()

Fl = 0

# цвет(х,у) = цвет закраски

win.image.setPixel(x, y, fill)

# заполняем интервал слева от затравки

x = x - 1

while win.image.pixel(x, y) != edge:

   win.image.setPixel(x, y, fill)

   x = x - 1

 

# сохраняем крайний слева пиксел

xl = x + 1

x = xt

# заполняем интервал справа от затравки

x = x + 1

 

while win.image.pixel(x, y) != edge:

   win.image.setPixel(x, y, fill)

   x = x + 1

# сохраняем крайний справа пиксел

xr = x - 1

y = y + 1

x = xl

# ищем затравку на строке выше

while x <= xr:

   Fl = 0

   while win.image.pixel(x, y) != edge and win.image.pixel(x, y) != fill and x <= xr:

       if Fl == 0:

           Fl = 1

       x = x + 1

 

   if Fl == 1:

       if x == xr and win.image.pixel(x, y) != fill and win.image.pixel(x, y) != edge:

           stack.append(QPointF(x, y))

       else:

           stack.append(QPointF(x - 1, y))

       Fl = 0

 

 

   xt = x

   while (win.image.pixel(x, y) == edge or win.image.pixel(x, y) == fill) and x < xr:

       x = x + 1

 

   if x == xt:

       x = x + 1

 

y = y - 2

x = xl

while x <= xr:

   Fl = 0

   while win.image.pixel(x, y) != edge and win.image.pixel(x, y) != fill and x <= xr:

       if Fl == 0:

           Fl = 1

       x = x + 1

 

 

   if Fl == 1:

       if x == xr and win.image.pixel(x, y) != fill and win.image.pixel(x, y) != edge:

           stack.append(QPointF(x, y))

       else:

           stack.append(QPointF(x - 1, y))

       Fl = 0

 

 

   xt = x

   while (win.image.pixel(x, y) == edge or win.image.pixel(x, y) == fill) and x < xr:

       x = x + 1

 

   if x == xt:

       x = x + 1`

 


Дата добавления: 2019-01-14; просмотров: 1012; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!