[C#] StackOverflowException in metodo ricorsivo

sebax

Utente Attivo
1,460
406
CPU
Intel i7 2600K @ 4.7ghz -> 5.66Ghz bench
Dissipatore
EK Supreme HF FullNickel
Scheda Madre
Gigabyte P67A-UD5-B3
HDD
Samsung EVO 256 GB + 1TB HDD
RAM
G.Skill ECO 1600 CL7 + 16 GB Corsair 1600 @ 2260mhz 7-10-7-25-2T bench
GPU
ASUS ENGTX570 DirectCU II (mod bios) -> EK DCII FullNickel @ 1ghz bench
Audio
Integrato Realtek HD
Monitor
Samsung s22b150 1920x1080
PSU
Enermax Modu 82+ 625W
Case
DimasTech Easy 2.5 Black Graphite + Laing 500Plus + EK XtX 360 + Nanoxia Fx2000 + Rehobus
OS
Linux Mint
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:
 

Talos

Utente Èlite
4,801
1,233
CPU
i5 2500k+EK 240 LTX/ AthlonII x2 255 + CM Hyper 212+
Scheda Madre
GIGABYTE P67A-UD4-B3/asrock A770DE+
HDD
Crucial m4 64GB/WD Caviar Black 500Gb /Seagate Barracuda 750GB / maxtor 500 gb
RAM
XMS3 12 GB DDR3-1600Mhz Cl9/Kingston hyperx DDR2 cl7 1066MHz 2x2GB
GPU
GTX1080 MSI Armor OC / 7970 Lightning @1200 / Sapphire HD5770
PSU
Hx850 Corsair / Vx450 corsair
Case
Corsair 600T White
OS
win 10
sto facendo appello a tutto ciò che ho imparato l'anno scorso a scuola... solo che non mi ricordo una mazza :asd:
 

sebax

Utente Attivo
1,460
406
CPU
Intel i7 2600K @ 4.7ghz -> 5.66Ghz bench
Dissipatore
EK Supreme HF FullNickel
Scheda Madre
Gigabyte P67A-UD5-B3
HDD
Samsung EVO 256 GB + 1TB HDD
RAM
G.Skill ECO 1600 CL7 + 16 GB Corsair 1600 @ 2260mhz 7-10-7-25-2T bench
GPU
ASUS ENGTX570 DirectCU II (mod bios) -> EK DCII FullNickel @ 1ghz bench
Audio
Integrato Realtek HD
Monitor
Samsung s22b150 1920x1080
PSU
Enermax Modu 82+ 625W
Case
DimasTech Easy 2.5 Black Graphite + Laing 500Plus + EK XtX 360 + Nanoxia Fx2000 + Rehobus
OS
Linux Mint
: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:

lorigio

Utente Attivo
817
238
CPU
Athlon II x3 435 With Noctua NH-D14
Scheda Madre
Asus M5A99X EVO AM3+
HDD
1TB + 160gb + WD My Passport Essential 500gb
RAM
Kingston ddr3 9-9-9-24 6gb 1333mhz
GPU
Gigabyte 5670 790mhz
Monitor
Samsung 22 pollici P2270HD
PSU
Corsair 400watt
Case
Cm 690 II advanced
OS
Windows 7 32 bit
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);
 

sebax

Utente Attivo
1,460
406
CPU
Intel i7 2600K @ 4.7ghz -> 5.66Ghz bench
Dissipatore
EK Supreme HF FullNickel
Scheda Madre
Gigabyte P67A-UD5-B3
HDD
Samsung EVO 256 GB + 1TB HDD
RAM
G.Skill ECO 1600 CL7 + 16 GB Corsair 1600 @ 2260mhz 7-10-7-25-2T bench
GPU
ASUS ENGTX570 DirectCU II (mod bios) -> EK DCII FullNickel @ 1ghz bench
Audio
Integrato Realtek HD
Monitor
Samsung s22b150 1920x1080
PSU
Enermax Modu 82+ 625W
Case
DimasTech Easy 2.5 Black Graphite + Laing 500Plus + EK XtX 360 + Nanoxia Fx2000 + Rehobus
OS
Linux Mint
: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:
 

Talos

Utente Èlite
4,801
1,233
CPU
i5 2500k+EK 240 LTX/ AthlonII x2 255 + CM Hyper 212+
Scheda Madre
GIGABYTE P67A-UD4-B3/asrock A770DE+
HDD
Crucial m4 64GB/WD Caviar Black 500Gb /Seagate Barracuda 750GB / maxtor 500 gb
RAM
XMS3 12 GB DDR3-1600Mhz Cl9/Kingston hyperx DDR2 cl7 1066MHz 2x2GB
GPU
GTX1080 MSI Armor OC / 7970 Lightning @1200 / Sapphire HD5770
PSU
Hx850 Corsair / Vx450 corsair
Case
Corsair 600T White
OS
win 10
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:
 

sebax

Utente Attivo
1,460
406
CPU
Intel i7 2600K @ 4.7ghz -> 5.66Ghz bench
Dissipatore
EK Supreme HF FullNickel
Scheda Madre
Gigabyte P67A-UD5-B3
HDD
Samsung EVO 256 GB + 1TB HDD
RAM
G.Skill ECO 1600 CL7 + 16 GB Corsair 1600 @ 2260mhz 7-10-7-25-2T bench
GPU
ASUS ENGTX570 DirectCU II (mod bios) -> EK DCII FullNickel @ 1ghz bench
Audio
Integrato Realtek HD
Monitor
Samsung s22b150 1920x1080
PSU
Enermax Modu 82+ 625W
Case
DimasTech Easy 2.5 Black Graphite + Laing 500Plus + EK XtX 360 + Nanoxia Fx2000 + Rehobus
OS
Linux Mint
allegato codice completo del file form1.cs non includente la gestione dell'interfaccia e della classe Program:)
 
Ultima modifica:

lorigio

Utente Attivo
817
238
CPU
Athlon II x3 435 With Noctua NH-D14
Scheda Madre
Asus M5A99X EVO AM3+
HDD
1TB + 160gb + WD My Passport Essential 500gb
RAM
Kingston ddr3 9-9-9-24 6gb 1333mhz
GPU
Gigabyte 5670 790mhz
Monitor
Samsung 22 pollici P2270HD
PSU
Corsair 400watt
Case
Cm 690 II advanced
OS
Windows 7 32 bit
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.
 

sebax

Utente Attivo
1,460
406
CPU
Intel i7 2600K @ 4.7ghz -> 5.66Ghz bench
Dissipatore
EK Supreme HF FullNickel
Scheda Madre
Gigabyte P67A-UD5-B3
HDD
Samsung EVO 256 GB + 1TB HDD
RAM
G.Skill ECO 1600 CL7 + 16 GB Corsair 1600 @ 2260mhz 7-10-7-25-2T bench
GPU
ASUS ENGTX570 DirectCU II (mod bios) -> EK DCII FullNickel @ 1ghz bench
Audio
Integrato Realtek HD
Monitor
Samsung s22b150 1920x1080
PSU
Enermax Modu 82+ 625W
Case
DimasTech Easy 2.5 Black Graphite + Laing 500Plus + EK XtX 360 + Nanoxia Fx2000 + Rehobus
OS
Linux Mint
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
 

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!