Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
(Румянцев)Задания к лабораторным.doc
Скачиваний:
5
Добавлен:
22.12.2018
Размер:
641.02 Кб
Скачать

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

Используя стек, можно разработать простой алгоритм заполнения гранично-определенной области. Стек — это просто массив или другая структура данных, в которую можно последовательно помещать значения и из которой их можно последовательно извлекать.

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

всплывают или поднимаются вверх на один уровень. Такой стек называется стеком прямого действия или стеком с дисциплиной обслуживания «первым пришел, последним обслужен» (FILO). Простой алгоритм заполнения с затравкой можно представить в следующем виде:

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

Поместить затравочный пиксел в стек

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

Извлечь пиксел из стека

Присвоить пикселу требуемое значение

Для каждого из соседних к текущему 4-связных пикселов проверить: является ли он граничным пикселом или не присвоено ли уже пикселу требуемое значение. Проигнорировать пиксел в любом из этих двух случаев. В противном случае поместить пиксел в стек. Алгоритм можно модифицировать для 8-связных областей, если просматривать 8-связные пикселы, а не только 4-связные.

private void PourLine(Int32 xx, Int32 yy, Color CGr, Color CZ)

{

push(xx, yy);

Int32 x = 0, y = 0;

CGr = Color.FromArgb(0, 0, 0);

CZ = Color.FromArgb(0, 0, 0);

Color CF = bmp.GetPixel(xx, yy);

while (beg != end)

{

Pop(ref x, ref y);

bmp.SetPixel(x, y, CZ);

Int32 t_x = x;

x++;

while (bmp.GetPixel(x, y) == CF)

{

PputPixel(x, y, CZ);

x++;

}

Int32 xr = x - 1;

x = t_x;

x--;

while (bmp.GetPixel(x, y) == CF)

{

PputPixel(x, y, CZ);

x--;

}

Int32 xleft = x + 1;

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

x = xleft;

y++;

while (x <= xr)

{

Int32 F = 0;

while (bmp.GetPixel(x, y) != CGr && bmp.GetPixel(x, y) != CZ && x < xr)

{

if (F == 0) F = 1;

x++;

}

if (F == 1)

if (x == xr && bmp.GetPixel(x, y) != CGr && bmp.GetPixel(x, y) != CZ) push(x, y);

else push(x - 1, y);

F = 0;

Int32 xv = x;

while ((bmp.GetPixel(x, y) == CGr || bmp.GetPixel(x, y) == CZ) && (x < xr)) x++;

if (x == xv) x++;

}

}

push(xx, yy - 1);

while (beg != end)

{

Pop(ref x, ref y);

bmp.SetPixel(x, y, CZ);

Int32 t_x = x;

x++;

while (bmp.GetPixel(x, y) == CF)

{

PputPixel(x, y, CZ);

x++;

}

Int32 xr = x - 1;

x = t_x;

x--;

while (bmp.GetPixel(x, y) == CF)

{

PputPixel(x, y, CZ);

x--;

}

Int32 xleft = x + 1;

//ищем затравку на строке ниже}

x = xleft;

y--;

while (x <= xr)

{

Int32 F = 0;

while (bmp.GetPixel(x, y) != CGr && bmp.GetPixel(x, y) != CZ && x < xr)

{

if (F == 0) F = 1;

x++;

}

if (F == 1)

if (x == xr && bmp.GetPixel(x, y) != CGr && bmp.GetPixel(x, y) != CZ) push(x, y);

else push(x - 1, y);

F = 0;

Int32 xv = x;

while ((bmp.GetPixel(x, y) == CGr || bmp.GetPixel(x, y) == CZ) && (x < xr)) x++;

if (x == xv) x++;

}

}

}

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)

{

if (Printing == 1)

Down = 1;

if (l == 1)

{

PourLine(e.X, e.Y, Color.Black, Color.Black);

}

}

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)

{

Down = 0;

}

Int32 xl, yl;

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)

{

if (Down == 1)

Gr.DrawLine(p, xl, yl, e.X, e.Y);

xl = e.X; yl = e.Y;

this.pictureBox1.Image = bmp;

}

Int32[] sx = new Int32[1000000];

Int32[] sy = new Int32[1000000];

Int32 beg = 0, end = 0;

private void push(Int32 x, Int32 y)

{

sx[end] = x;

sy[end] = y;

end++;

}

private void Pop(ref Int32 x, ref Int32 y)

{

x = sx[beg];

y = sy[beg];

beg++;

}