Рис. 4.29. Граничное заполнение по полосам пикселей для четырехсвязной области: а) исходная строка развертки с закрашенной полосой пикселей, где показано положение исходной точки (пустой кружок) и занесенные в стек положения для полос пикселей в соседних строках развертки; б) закрашенная полоса пикселей в первой строке развертки над начальной строкой развертки и текущее содержимое стека; в) закрашенные полосы пикселей в первых двух строках развертки над исходной строкой развертки и текущее содержимое стека; г) заполненные полосы пикселей для правой верхней части заданной области и остальные положения из стека, которые подлежат обработке
Рис. 4.30. Область, которая задается с помощью нескольких цветных границ
АЛГОРИТМ ПОТОКОВОГО ЗАПОЛНЕНИЯ
Иногда нужно закрасить (или перекрасить) область, которая не описывается с помощью одной цветной границы. На рис. 4.30 показана область, ограниченная нескольким областями различных цветов. Такие участки можно рисовать, заменяя заданный внутренний цвет, а не стараясь найти определенную цветную границу. Эта процедура заполнения называется алгоритмом потокового заполнения. В таком случае закрашивание начинается с заданной внутренней точки (х, у), причем всем пикселям, значения которых на данный момент соответствуют заданному цвету внутренней области, присваиваются новые значения, соответствующие искомому цвету заполнения. Если область, которая подлежит перекрашиванию, состоит из больше, чем одного, внутреннего цвета, сначала можно изменить значения пикселей таким образом, чтобы все внутренние точки стали одинакового цвета. После этого, используя либо четырехсвязный, либо восьмисвязный подход, проходят все положения пикселей по очереди, пока не будет изменен цвет всех внутренних точек. Следующая процедура служит для потокового заполнения четырехсвязной области рекурсивным способом, начиная с заданной входной точки.
void floodFill4 (int х, int у, int fillColor,
int interiorColor) {
int color;
/* Устанавливается текущий цвет fillColor, после чего выполняются следующие операции.
*/
getPixel (х, у, color); if (color = interiorColor) { setPixel (x, y);
/* Цвет пикселя устанавливается равным fillColor.*/ floodFill4 (x + 1, у, fillColor, interiorColor);
floodFill4 (x - 1, y, fillColor, interiorColor);
floodFill4 (x, у + 1, fillColor, interiorColor);
floodFill4 (x, у - 1, fillColor, interiorColor)
}
}
Вышеприведенную процедуру можно изменить таким образом, чтобы уменьшить объем памяти, необходимый для создания стека, для чего закрашиваются горизонтальные полосы пикселей (см. обсуждение алгоритма граничного заполнения). При таком подходе в стек заносятся только начальные положения тех полос пикселей, значение которых равно interiorColor. Этапы этого измененного алгоритма потокового заполнения такие же, как показано на рис. 4.29 для граничного заполнения. Начиная с первой точки каждой полосы, значения пикселей заменяются до тех пор, пока не встретится значение, отличное от interiorColor.