// pastreaza coordonata y a punctului de start al muchiei si inversul pantei (1/m) pt fiecare muchie // ajusteaza si pastreaza coordonata y a punctului final pt muchiile care sunt membrul inferior // dintr-o pereche de muchii monoton crescatoare sau descrescatoare void AjusteazaMuchie(Point inf, Point sup, int yComp, Muchie muchie, Muchie[] muchii) { muchie.dxScan = (float)(sup.X - inf.X) / (sup.Y - inf.Y); muchie.xIntersectie = inf.X; if (sup.Y < yComp) muchie.ySup = sup.Y - 1; else muchie.ySup = sup.Y; InsereazaMuchie(muchii[inf.Y], muchie); }
public void ScanFill(int cnt, Point[] puncte, Bitmap bmp, Color c, int windowHeight, PictureBox box) { bitm = bmp; pb = box; // bmp.Save("e:\\test.bmp"); cl = c; muchii = new Muchie[windowHeight]; int i; for (i = 0; i < windowHeight; i++) { muchii[i] = new Muchie(); muchii[i].next = null; } ConstruiesteListaMuchii(cnt, puncte, muchii); activa = new Muchie(); activa.next = null; scan = 0; //for (scan = 0; scan < windowHeight; scan++) //{ // ConstruiesteListaActiva(scan, activa, muchii); // if (activa.next != null) // { // FillScan(scan, activa, bmp, c); // UpdateListaActiva(scan, activa); // ResorteazaListaActiva(activa); // // Task.Delay(1000); // } //} timer.Enabled = true; timer.Interval = 10; timer.Tick += timer_Tick; timer.Start(); }
// aici umplem poligonul cu alg scanline si // facem poligonul sa revina la culoarea anterioara cu click dreapta private void pictureBox_MouseClick(object sender, MouseEventArgs ev) { Muchie m = new Muchie(); Color r = Color.Black; BoundaryFill bf = new BoundaryFill(); switch (ev.Button) { case MouseButtons.Left: if (umpleGeneratScan) { if (CursorInInterior(puncte, ev.Location)) { statusLabel.Enabled = true; statusLabel.Visible = true; statusLabel.Text = "Se umple poligon generat cu Scan-Line"; colorD = new ColorDialog(); colorD.ShowDialog(); r = colorD.Color; statusLabel.ForeColor = r; m.ScanFill((int)numere.Value, puncte, bmp, r, pictureBox1.Height, pictureBox1); pictureBox1.Image = bmp; pictureBox1.Refresh(); if (bmp != null) { alfa = bmp.GetPixel(ev.Location.X, ev.Location.Y).A; green = bmp.GetPixel(ev.Location.X, ev.Location.Y).G; red = bmp.GetPixel(ev.Location.X, ev.Location.Y).R; blue = bmp.GetPixel(ev.Location.X, ev.Location.Y).B; } } } else if (umpleGeneratBound4 && CursorInInterior(puncte, ev.Location)) { statusLabel.Enabled = true; statusLabel.Visible = true; statusLabel.Text = "Se umple poligon generat cu Boundary-Fill 4"; colorD = new ColorDialog(); colorD.ShowDialog(); r = colorD.Color; statusLabel.ForeColor = r; bf.BoundaryFill4(ev.Location.X, ev.Location.Y, r, culoareContur, bmp, pictureBox1); umpleGeneratBound4 = false; pictureBox1.Image = bmp; pictureBox1.Refresh(); } else if (umpleGeneratBound8 && CursorInInterior(puncte, ev.Location)) { statusLabel.Enabled = true; statusLabel.Visible = true; statusLabel.Text = "Se umple poligon generat cu Boundary-Fill 8"; colorD = new ColorDialog(); colorD.ShowDialog(); r = colorD.Color; statusLabel.ForeColor = r; bf.BoundaryFill8(ev.Location.X, ev.Location.Y, r, culoareContur, bmp, pictureBox1); umpleGeneratBound8 = false; pictureBox1.Image = bmp; } else if (umpleGeneratflood4 && CursorInInterior(puncte, ev.Location)) { statusLabel.Enabled = true; statusLabel.Visible = true; statusLabel.Text = "Se umple poligon generat cu Flood-Fill 4"; colorD = new ColorDialog(); colorD.ShowDialog(); r = colorD.Color; statusLabel.ForeColor = r; bf.FloodFill4(ev.Location.X, ev.Location.Y, r, bmp.GetPixel(ev.Location.X, ev.Location.Y), bmp, pictureBox1); umpleGeneratflood4 = false; pictureBox1.Image = bmp; } else if (umpleGeneratflood8 && CursorInInterior(puncte, ev.Location)) { statusLabel.Enabled = true; statusLabel.Visible = true; statusLabel.Text = "Se umple poligon generat cu Flood-Fill 8"; colorD = new ColorDialog(); colorD.ShowDialog(); r = colorD.Color; statusLabel.ForeColor = r; bf.FloodFill8(ev.Location.X, ev.Location.Y, r, bmp.GetPixel(ev.Location.X, ev.Location.Y), bmp, pictureBox1); umpleGeneratflood8 = false; pictureBox1.Image = bmp; } else if (bfisierApasat) { if (fisBoundary4) { statusLabel.Enabled = true; statusLabel.Visible = true; statusLabel.Text = "Se umple poligon din fisier cu Boundary-Fill 4"; colorD = new ColorDialog(); colorD.ShowDialog(); r = colorD.Color; statusLabel.ForeColor = r; Bitmap bitm = new Bitmap(pictureBox1.Image); bf.BoundaryFill4(ev.Location.X, ev.Location.Y, r, Color.Black, bitm, pictureBox1); pictureBox1.Image = bitm; fisBoundary4 = false; } else if (fisBoundary8) { colorD = new ColorDialog(); colorD.ShowDialog(); r = colorD.Color; statusLabel.Enabled = true; statusLabel.Visible = true; statusLabel.ForeColor = r; statusLabel.Text = "Se umple poligon din fisier cu Boundary-Fill 8"; Bitmap bitm = new Bitmap(pictureBox1.Image); bf.BoundaryFill8(ev.Location.X, ev.Location.Y, r, Color.Black, bitm, pictureBox1); pictureBox1.Image = bitm; fisBoundary8 = false; } else if (fisFlood4) { statusLabel.Enabled = true; statusLabel.Visible = true; statusLabel.ForeColor = r; statusLabel.Text = "Se umple poligon din fisier cu Flood-Fill 4"; colorD = new ColorDialog(); colorD.ShowDialog(); r = colorD.Color; Bitmap bitm = new Bitmap(pictureBox1.Image); bf.FloodFill4(ev.Location.X, ev.Location.Y, r, bitm.GetPixel(ev.Location.X, ev.Location.Y), bitm, pictureBox1); pictureBox1.Image = bitm; fisFlood4 = false; } else if (fisFlood8) { statusLabel.Enabled = true; statusLabel.Visible = true; statusLabel.Text = "Se umple poligon din fisier cu Flood-Fill 8"; colorD = new ColorDialog(); colorD.ShowDialog(); r = colorD.Color; statusLabel.ForeColor = colorD.Color; Bitmap bitm = new Bitmap(pictureBox1.Image); bf.FloodFill8(ev.Location.X, ev.Location.Y, r, bitm.GetPixel(ev.Location.X, ev.Location.Y), bitm, pictureBox1); pictureBox1.Image = bitm; fisFlood8 = false; } bfisierApasat = false; } break; case MouseButtons.Right: if (umpleGeneratScan) { if (CursorInInterior(puncte, ev.Location)) { m.ScanFill((int)numere.Value, puncte, bmp, c, pictureBox1.Height, pictureBox1); pictureBox1.Image = bmp; pictureBox1.Invalidate(); } umpleGeneratScan = false; } break; } }
void ConstruiesteListaActiva(int scan, Muchie activa, Muchie[] muchii) { Muchie p, q; if (scan >= 0 && scan < 410) p = muchii[scan].next; else p = muchii[409].next; while (p != null) { q = p.next; InsereazaMuchie(activa, p); p = q; } }
// stergem muchii complete, update xIntersectie pt muchiile incomplet procesate void UpdateListaActiva(int scan, Muchie activa) { Muchie q = activa, p = activa.next; while (p != null) if (scan >= p.ySup) { p = p.next; StergeDupa(q); } else { p.xIntersectie += p.dxScan; q = p; p = p.next; } }
void StergeDupa(Muchie q) { Muchie p = q.next; q.next = p.next; p = null; }
void ResorteazaListaActiva(Muchie activa) { Muchie q, p = activa.next; activa.next = null; while (p != null) { q = p.next; InsereazaMuchie(activa, p); p = q; } }
// insereaza muchia in lista in ordinea crescatoare a campului xIntersectie void InsereazaMuchie(Muchie lista, Muchie muchie) { Muchie p, q = lista; p = q.next; while (p != null) { if (muchie.xIntersectie < p.xIntersectie) p = null; else { q = p; p = p.next; } } muchie.next = q.next; q.next = muchie; }
void FillScan(int scan, Muchie activa, Bitmap b, Color c) { Muchie p1, p2; int i; p1 = activa.next; while (p1 != null) { p2 = p1.next; for (i = (int)p1.xIntersectie; i < p2.xIntersectie; i++) { b.SetPixel(i, scan, c); Task.Delay(1000); //as vrea sa vad fiecare linie } p1 = p2.next; } }
void ConstruiesteListaMuchii(int cnt, Point[] puncte, Muchie[] muchii) { Muchie muchie; Point p1, p2; int i, yPrev = puncte[cnt - 2].Y; p1 = new Point(); p1.X = puncte[cnt - 1].X; p1.Y = puncte[cnt - 1].Y; for (i = 0; i < cnt; i++) { p2 = puncte[i]; if (p1.Y != p2.Y) { // linie care nu e orizontala adica muchie = new Muchie(); if (p1.Y < p2.Y) // muchie care se duce in sus AjusteazaMuchie(p1, p2, yNext(i, cnt, puncte), muchie, muchii); else // muchie descrescatoare AjusteazaMuchie(p2, p1, yPrev, muchie, muchii); } yPrev = p1.Y; p1 = p2; } }