[C#] StackOverflowException in metodo ricorsivo

Pubblicità

sebax

Utente Attivo
Messaggi
1,460
Reazioni
406
Punteggio
71
ciao a tutti.
sto cercando di fare un programmino simile a Paint di windows e sto cercando di scrivere la funzione "riempi" (il secchiello insomma:D)

e ho scritto questa funzione:
Codice:
        void colora(Point p, Color c1, Color c2)
        {
            b.SetPixel(p.X, p.Y, c2);

            //creo la griglia di 8 pixel attorno a quello cliccato
            Point[] A = new Point[8];
            A[0] = new Point(p.X, p.Y + 1);
            A[1] = new Point(p.X, p.Y - 1);
            A[2] = new Point(p.X + 1, p.Y - 1);
            A[3] = new Point(p.X + 1, p.Y + 1);
            A[4] = new Point(p.X + 1, p.Y);
            A[5] = new Point(p.X - 1, p.Y + 1);
            A[6] = new Point(p.X - 1, p.Y - 1);
            A[7] = new Point(p.X - 1, p.Y);
            
            int i;
            for (i = 0; i < 8; i++)
            {
                if (b.GetPixel(A[i].X, A[i].Y) == c1)
                {
                    colora(A[i], c1, c2);
                }
            }
        }

invocata così sull'evento click sulla PictureBox:
Codice:
Point click = ((MouseEventArgs)e).Location;
                colora(click, b.GetPixel(click.X, click.Y), Color.Red);

in cui b è l'oggetto Bitmap sul quale sto disegnando (assieme a Graphics)

il problema è che se cerco di riempire un'area più grande di circa 100pixel mi da l'eccezzione StackOverflowException ma il mio non è un ciclo infinito:cav: ha solo parecchie iterazioni:asd:

PS: so che la parte che crea la griglia di 9 pixel è incompleta perchè manca la parte che evita di andare fuori dai limiti della size di b, ma così funziona se in precedenza faccio a caso delle figure chiuse entro i limiti di b:ok:

idee??:help: magari trasformando la funzione ricorsiva in un qualche ciclo for o while:look:
 
sto facendo appello a tutto ciò che ho imparato l'anno scorso a scuola... solo che non mi ricordo una mazza :asd:
 
:lol::lol::lol::lol:

più che C# è più un problema di logica e di trovare l'algoritmo giusto:cav:


EDIT: AGGIORNAMENTO: ho anche provato a rendere l'array A di Point globale (cosa decisamente migliore dal punto di vista del "risparmio" di memoria:D) con valori +1,-1 e 0 per le 9 combinazioni e non da più l'overflow sulla dichiarazione dell'array come accadeva prima, ma in
Application.Run(new Form1()); :boh:

:help:
 
Ultima modifica:
void colora(Point p, Color c1, Color c2)
{
b.SetPixel(p.X, p.Y, c2);

//creo la griglia di 8 pixel attorno a quello cliccato
Point[] A = new Point[8];
A[0] = new Point(p.X, p.Y + 1);
A[1] = new Point(p.X, p.Y - 1);
A[2] = new Point(p.X + 1, p.Y - 1);
A[3] = new Point(p.X + 1, p.Y + 1);
A[4] = new Point(p.X + 1, p.Y);
A[5] = new Point(p.X - 1, p.Y + 1);
A[6] = new Point(p.X - 1, p.Y - 1);
A[7] = new Point(p.X - 1, p.Y);

int i;
for (i = 0; i < 8; i++)
{
if (b.GetPixel(A.X, A.Y) == c1)
{
colora(A, c1, c2);
}
}
}


io farei cosi

Codice:
      void colora(Point p, Color c1, Color c2)
        {
            b.SetPixel(p.X, p.Y, c2);
        }

      void clickaction(Point p, Color c1, Color c2)
        {         

           
            Point[] A = new Point[8];
            A[0] = new Point(p.X, p.Y + 1);
            A[1] = new Point(p.X, p.Y - 1);
            A[2] = new Point(p.X + 1, p.Y - 1);
            A[3] = new Point(p.X + 1, p.Y + 1);
            A[4] = new Point(p.X + 1, p.Y);
            A[5] = new Point(p.X - 1, p.Y + 1);
            A[6] = new Point(p.X - 1, p.Y - 1);
            A[7] = new Point(p.X - 1, p.Y);
            
            int i;
            for (i = 0; i < 8; i++)
            {
                if (b.GetPixel(A[i].X, A[i].Y) == c1)
                {
                    colora(A[i], c1, c2);
                }
            }
        }

Point click = ((MouseEventArgs)e).Location;
                clickaction(click, b.GetPixel(click.X, click.Y), Color.Red);
 
:nunu:
così ne coloro solo 9, ovvero quello che ho premuto e quelli adiacenti:D... la funzione "colora" che ho scritto io funziona, però da quel erroraccio perché vado fuori dallo stack:cav:
è scritta così -ricorsiva- perché per ogni pixel che trovo gestisco controllo gli adiacenti in una sorta di "macchia d'olio" per colorare tutti i pixel adiacenti di uno stesso colore:sisi:
 
il "punto" ( concedimi il gioco di parole :P ) è che vedendolo scritto così non riesco a capirci un tubo , invece se ce l'ho sotto mano , magari mi ci raccapezzo :|

ora però ad essere sincero , non mi ricordo lessico , semantica e sintassi quindi sono utile come un freezer al polo nord :lol:
 
allegato codice completo del file form1.cs non includente la gestione dell'interfaccia e della classe Program:)
 
Ultima modifica:
for (i = 0; i < 8; i++)
{
if (b.GetPixel(A.X, A.Y) == c1)
{
colora(A, c1, c2);
}
}


Se fai cosi va all'infinito perchè richiama 8 volte colora e a sua volta lo richiama altre 8x8 volte ecc.
 
no, la if è fatta apposta, chiama di nuovo colora solo se il colore del pixel estratto è uguale a quello in cui si è premuto:D

sebax ha detto:
PS: so che la parte che crea la griglia di 9 pixel è incompleta perchè manca la parte che evita di andare fuori dai limiti della size di b, ma così funziona se in precedenza faccio a caso delle figure chiuse entro i limiti di b

ripeto, il metodo funziona perfettamente su aree piccole
 
Pubblicità
Pubblicità
Indietro
Top