Algoritmo de relleno (bote de pintura)

Buenas, por mero aburrimiento, ando mirando como hacer este algoritmo pero... sin usar recursividad, ya que en todas las plataformas la pila no es igual, y además, tiene un límite.

¿Alguien tiene idea de por donde empezar? O... Por favor, link de la wikipedia no -.-"

Saludos!
Programe algo parecido hace poco para el trabajo, aunque lo hice recursivamente.

Si no quieres hacerlo recursivo se me ocurre la siguiente manera:

colorViejo;   // Color a remplazar
colorNuevo;   // Color por el cual reemplazar
listaAPintar;   // Lista que contendrá todos los pixeles a pintar
listaAComprobar;// Lista que contendrá pixeles en los que hay que mirar sus adyacentes
posicionClic;   // Punto sobre el que se vierte el bote de pintura

// Agregamos el pixel sobre el que se ha hecho clic a la lista a comprobar
listaAComprobar.Add( pixels[Clic.x, clic.y] );

// Vamos comprobando todos los pixeles pendientes
while( listaAComprobar.Lenght > 0 )
{
   // Todos los pixels pendientes son del color a reemplazar, por lo que lo sacamos
   // de la lista y lo ponemos a pintar
   pixelActual = listaAComprobar[0];
   listaAComprobar.Drop( pixelActual );
   listaAPintar.Add( pixelActual );
   
   // Comprobamos sus adyacentes
   if( pixels[ pixelActual.x - 1, pixelActual.y ] )
      pixelsAComprobar.Add( pixels[ pixelActual.x - 1, pixelActual.y ] )
   else if( pixels[ pixelActual.x + 1, pixelActual.y ] )
      pixelsAComprobar.Add( pixels[ pixelActual.x + 1, pixelActual.y ] )
   else if( pixels[ pixelActual.x, pixelActual.y - 1 ] )
      pixelsAComprobar.Add( pixels[ pixelActual.x, pixelActual.y - 1 ] )
   else if( pixels[ pixelActual.x, pixelActual.y + 1 ] )
      pixelsAComprobar.Add( pixels[ pixelActual.x, pixelActual.y + 1 ] )
}

// Pintamos los pixels
foreach pixel in listaAPintar
   pixel.color = colorNuevo


Faltaría el control de índices para no salirte de la imagen y demás, pero creo que funcionaría. De todos modos lo acabo de hacer al vuelo en una especie de pseudoC# ( :p ) ahora mismo directamente en el notepad, por lo que puede que no funcione o tenga errores. Por descontado, seguramente tampoco sea la forma más óptima.

EDIT: Me acabo de daro cuenta de que el algoritmo no terminaría, ya que no se está mirando que los pixels ya comprobados no se vuelvan a comprobar. Se arreglaría con una lista de comprobados y al insertar un pixel en listaAComprobar mirar si ya existe en esta lista o en la de ya comprobados.
Pues voy a ponerme a ver si sonsaco algo en claro. Por si entiendes del tema, intento hacerlo en C.

Gracias.

Edito: Cierto, no termina, tengo que o ir pintando, o usar otra variable en la que almaceno el color y veo si previamente ese pixel no es colorBase, si no que ya esta pintado. Poco a poco avanzo ^^, yo creo que esta noche consigo algo semi decente.

Edito2: Conseguido, pero es realmente lento... quizás sea porque lo uso en la Nintendo DS y claro... no es tan rápida como un PC ni de lejos jaj
Gracias!
Para pasar algo recursivo a algo iterativo usa una pila
Gammenon escribió:Para pasar algo recursivo a algo iterativo usa una pila
Si bueno, he usado un array con dos indices, uno que va comprobando y otro que va añadiendo al array.

He conseguido eliminar la mayoria de bucles, ahorrando tiempo, ahora va perfect ^^

Gracias.
(mensaje borrado)
5 respuestas