2015-04-28 21 views
6

Ho bisogno di scrivere un algoritmo di riempimento flood per colorare i pixel di un'immagine che sono all'interno dei bordi neri. Ho scritto quanto segue sulla base di alcuni post qui su SO:Java Flood Fill issue

private Queue<Point> queue = new LinkedList<Point>(); 
private int pickedColorInt = 0; 

private void floodFill(Pixmap pixmap, int x, int y){ 
    //set to true for fields that have been checked 
    boolean[][] painted = new boolean[pixmap.getWidth()][pixmap.getHeight()]; 

    //skip black pixels when coloring 
    int blackColor = Color.rgba8888(Color.BLACK); 

    queue.clear(); 
    queue.add(new Point(x, y)); 

    while(!queue.isEmpty()){ 
     Point temp = queue.remove(); 
     int temp_x = temp.getX(); 
     int temp_y = temp.getY(); 

     //only do stuff if point is within pixmap's bounds 
     if(temp_x >= 0 && temp_x < pixmap.getWidth() && temp_y >= 0 && temp_y < pixmap.getHeight()) { 
      //color of current point 
      int pixel = pixmap.getPixel(temp_x, temp_y); 
      if (!painted[temp_x][temp_y] && pixel != blackColor) { 
       painted[temp_x][temp_y] = true; 
       pixmap.drawPixel(temp_x, temp_y, pickedColorInt); 

       queue.add(new Point(temp_x + 1, temp_y)); 
       queue.add(new Point(temp_x - 1, temp_y)); 
       queue.add(new Point(temp_x, temp_y + 1)); 
       queue.add(new Point(temp_x, temp_y - 1)); 

      } 
     } 
    } 
} 

Questo non funziona come previsto. Ad esempio, nella seguente immagine di prova: enter image description here

I rettangoli casuali si ricollegano a seconda di dove ho fatto clic. Ad esempio, facendo clic su un punto qualsiasi sotto il rettangolo viola si ricolora il rettangolo viola. Cliccando all'interno del rettangolo viola si ritorna al rettangolo verde. L'ho verificato e sto passando i parametri giusti al metodo, quindi il problema è probabilmente da qualche parte nel mio ciclo.

+3

Penso che * non * passi nei parametri corretti. Sembra che la tua coordinata Y sia sbagliata, perché il sistema di coordinate che stai usando è Y-up e un altro è Y-down. Prova 'y = pixmap.getHeight() - y' all'inizio del tuo metodo per invertire y. – noone

+0

Wow, non mi è nemmeno passato per la testa. Questo è un progetto libGDX dove ad esempio coordinate di scena, sprite, rettangoli e oggetti simili hanno una coordinata (0, 0) in basso a sinistra. Ma immagino che Pixmap usi in alto a sinistra per (0, 0). Grazie! –

+0

Questo ha risolto il tuo problema? Se lo facesse, lo scriverò come risposta, quindi non apparirà senza risposta. – noone

risposta

2

L'algoritmo è corretto, solo i parametri di input non lo sono.

I rettangoli casuali vengono ricolorati a seconda di dove ho fatto clic. Ad esempio, facendo clic su un punto qualsiasi sotto il rettangolo viola si ricolora il rettangolo viola. Cliccando all'interno del rettangolo viola si ritorna al rettangolo verde.

Se si guarda l'immagine, i rettangoli colorati non sono realmente casuali. Il vero problema è una coordinata Y errata. In particolare la tua coordinata Y è invertita.

Questo perché la maggior parte delle volte LibGDX utilizza un sistema di coordinate in alto a sinistra, su y, ma in caso di Pixmap è in alto a sinistra.

Una semplice soluzione per questo è solo invertire il valore Y facendo y = pixmap.getHeight() - y.

+0

Grazie @noone Ho usato questa soluzione nella mia libreria: https://github.com/Gornova/StrategyGameUtils – Vokail