Читайте также:
|
|
Зафарбовування – це зміна кольору масиву пікселів, що знаходяться поруч і мають однаковий колір, утворюючи замкнену область. Розробляючи алгоритми зафарбовування було розроблено та реалізовано 3 різні алгоритми: зафарбовування модифікованим методом «математичної хвилі», модифікований рекурсивний метод та порядкове зафарбовування.
Алгоритм мат. хвилі показано в лістингу 2.8.1.
Лістинг 2.8.1 Алгоритм зафарбовування «математичною хвилею»
Для малюнка створюється бінарна маска, яка відображає область, яка має бути зафарбована. Суть алгоритму полягає в тому, що виконується певна кількість ітерацій на яких алгоритм шукає зони що мають бути зафарбованими та перевіряє на предмет необхідності зафарбовування сусідні пікселі. Якщо їх треба зафарбувати, вони помічаються для зафарбовування. Таким чином на наступній ітерації всі наступні сусідні пікселі також будуть перевірені на необхідність зафарбовування. Зупинити пошук варто тоді, коли на якійсь із ітерації для зафарбування не було помічено жодного пікселя. Далі задача просто зафарбувати новим кольором область, що помічена для фарбування.
Суть модифікації даного алгоритма полягає у тому, що напрямок руху циклу зафарбовування змінюється з кожною наступною ітерацією. Це доцільно тому, що під час кожного проходу зафарбовуються усі пікселі від вже помічених в напрямку руху циклу. Таким чином кількість ітерацій зафарбовування можна скоротити в багато разів. Зразок роботи алгоритма можна побачити на рисунку 2.8.1.
Рис. 2.8.1 Робота алгоритму зафарбовування «мат. хвиля»
Модифікований рекурсивний метод представлено в лістингу 2.8.2.
int x= startX;Лістинг 2.8.2 Модифікований рекурсивний алгоритм зафарбовування
Суть рекурсивного алгоритму зафарбовування полягає у тому, що в момент визначення точки початку зафарбовування викликається функція, яка зафарбовує цей піксель та перевіряє сусідні пікселі на відповідність кольору. Якщо вони такого ж кольору, функція викликає сама себе для кожного з таких пікселів. Алгоритм закінчиться сам тоді, коли жодна з викликаних функцій не викличе себе сама, тобто тоді, коли більше не буде чого зафарбовувати.
Головною проблемою цього алгоритму є переповнення стеку викликів при досить великих малюнках. Саме тому алгоритм був модифікований для використання внутрішньої черги. Коли функція знаходить піксель, що підлягає зафарбовуванню, вона вносить його в чергу, яку потім обробляє. Обробляючи чергу, шукаються все нові і нові пікселі, які також вносяться в чергу. Алгоритм закінчується тоді, коли черга закінчується. Результат роботи алгоритма при використанні черги можна бачити на рис. 2.8.2, а при використанні стеку – на рис. 2.8.3.
Рис. 2.8.2 Демонстрація роботи модифікованого рекурсивного алгоритма зафарбовування з використанням черги
Рис. 2.8.3 Демонстрація роботи модифікованого рекурсивного алгоритма зафарбовування з використанням стеку
Алгоритм зафарбовування по рядкам показано в лістингу 2.8.3.
if (y < height -1 && valid(x, y + 1)){
set(x, y+1);
if (!validDown){
queue. add(y+1);
validDown = true;
}
}
if (y > 1 && valid(x, y - 1)){
set(x, y - 1);
if (!validUp){
queue. add(y - 1);
validUp = true;
}
}
}
}
}
Лістинг 2.8.3. Алгоритм зафарбовування по рядкам
Даний алгоритм, як і попередній, має в собі в основі чергу, але таку, яка зберігає не пікселі, а рядки. Потрапляючи на рядок, функція заповнює його по горизонталі, та водночас шукає рядки для зафарбовування вище та нижче себе. Якщо знаходить, додає їх до черги. Роботу даного алгоритму можна бачити на рис. 2.8.4.
Рис. 2.8.4 Демонстрація роботи алгоритму зафарбовування по рядках
Дата добавления: 2015-08-09; просмотров: 192 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Розроблення алгоритмів динамічного керування товщиною пензля | | | ОПИС ПРОГРАМНОГО ПРОДУКТУ |