Entwickler-Ecke
Multimedia / Grafik - Floodfill darstellen
roKR-91 - Do 10.12.09 21:37
Titel: Floodfill darstellen
hi...wir sollen inner schule (12te klasse) den FloodFill-algorithmus grafisch darstellen
einmal mir 4er nachbarschaft und dann mit 8er nachbarschaft...
hab das formular soweit fertig...jetz brauch ich "nur noch" das raster zeichnen (was nich das prob is) und dann ein objekt ausfüllen...und genau daran scheitert's das theoretische...also das was man rechnet geht alles soweit...ich weiß nur nich wie ich das grafisch umsetzen soll...hab i-wie keinen ansatz...
wär echt super wenn mir jemand sagen könnte wie ich das machen kann...danke schonmal im voraus ;)
Horst_H - Fr 11.12.09 12:54
Hallo,
wenn Du schon ein Raster hast und mit Floodfill loslegst, mußt Du doch nur innerhalb der floodfill-Routine ein paar Zeichenoperationen ausführen.
Wenn ein Feld getestet wird, die Farbe merken, das Feld auf dem Bildschirm zum Beispiel schwarz umranden ( Rechteck) ,etwas warten ~200 ms, Umrandung mit gemerkter Farbe löschen und weiter im Text, wenn das Feld eingefärbt wird, dies auch auf dem Bildschirm machen.
Gruß Horst
ene - Fr 11.12.09 13:08
Moin,
Für das Raster gilt doch, dass jedes Element 3 Zustände haben kann. 0 = Nicht aktiv, 1 = aktiv, 2 = Grenze. Wenn die Grenze wegfällt wirds noch einfacher.
Du beginnst als an einem Startpunkt und markierst eben die Punkte als aktiv, die es werden können:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| Procedure FloodFill(Const x,y: Integer); Begin Raster[x, y] := 1; If (Raster[x+1,y ]= 0) Then FloodFill(X+1, Y ); If (Raster[x-1,y ]= 0) Then FloodFill(X-1, Y ); If (Raster[x ,y+1]= 0) Then FloodFill(X , Y+1); If (Raster[x ,y-1]= 0) Then FloodFill(X , Y-1); End; |
Das ist Rekursiv und ruft alle umliegenden Punkte, die 0 sind auf. Beim Eintritt in dieses Element wird es zu 1. Was dabei noch fehlt ist die Begrezung da x und y nicht kleiner 0 sein können und nicht größer als dein Raster.
roKR-91 - Di 05.01.10 17:39
also ich hab mich in den ferien damit jetz gründlich beschäftigt...ich denk den rest krieg ich hin...lediglich an einer sache bin ich am verzweifeln...ich hab hier jetz son gebilde wo ich das floodfill drin ausführe...siehe bild...und da soll jetz halt noch ne diagonale (rote makierung) um die 8er nachbarschaft darzustellen...aber wie zeichne ich möglichst kurz ne diagonale??? klar ich könnte jetz jeden punkt einzeln füllen aber ich würd das gern so kurz wie möglich halten...
roKR-91 - Di 05.01.10 19:22
so ich hab jetz den wiki-bresenham der in basic geschrieben war in delphi geschrieben
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| procedure p_brese (xa, xe, ya, ye : integer); var x, y, dx, dy : integer; fehler : real; begin dx := xe - xa; dy := ye - ya;
x := xa; y := ya; setpixel(x,y); fehler := dx/2;
while x < 423 do x := x+1; fehler := fehler - dy; if fehler < 0 then begin y := y + 1; fehler := fehler + dx end; setpixel (x,y); end; |
und als aufruf :
Delphi-Quelltext
1:
| p_brese(330,423,220,313); |
jetz krieg ich aber die fehlermeldungen:
"[Fehler]Unit1.pas(10): Nicht genügend wirkliche Parameter" und
"[Fehler]Unit1.pas(19): Nicht genügend wirkliche Parameter"
Flamefire - Di 05.01.10 19:38
ich nehme mal an (sry meine zauberkugel ist etwas verstaubt) das zeile 10 und 19 die setPixel() aufrufe sind
es wäre also gut, wenn du die zugehörige funktionen noch mit postest.
ebenfalls angenommen (wieder die zauberkugel) ist, dass da einfach nur die farbe fehlt.
wenn du aber nur direkt diagonale linien zeichen willst (also abstand in x und y richtung ist gleich) brauchst du das nicht...
dann gehst du einfach in jedem schritt je 1 pixel in richtung des ziels in auf jeder achse
Christian S. - Di 05.01.10 19:40
Damit die while-Schleife einen Sinn ergibt, dürfte da auch noch ein begin .. end hingehören.
roKR-91 - Di 05.01.10 20:28
erstens: danke wegen der while schleife^^
zweitens: wie dumm kann man sein die farbe zu vergessen :D omg mein fehler...zumal es ja in der eingabehilfe steht :D
allerdings will die eingabehilfe folgendes : DC:HDC; x : integer; y : integer; color : cardinal
was is DC:HDC ???
und welche funktion meinst du? den aufruf hatte ich doch mit drin?
hier der ganze quelltext...
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, Buttons, ExtCtrls;
type TForm1 = class(TForm) PageControl1: TPageControl; BitBtn1: TBitBtn; TabSheet1: TTabSheet; TabSheet2: TTabSheet; BitBtn2: TBitBtn; RadioGroup1: TRadioGroup; Button1: TButton; Linie1: TPanel; Kreis1: TPanel; ComboBox1: TComboBox; Panel1: TPanel; Button2: TButton; bild: TImage; procedure Button2Click(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure p_figur (a,b : integer); begin with form1.bild.Canvas do begin brush.color := clblack; Floodfill(a,b,clblack,fsBorder); end; end;
procedure p_brese (xa, xe, ya, ye : integer); var x, y, dx, dy : integer; fehler : real; begin dx := xe - xa; dy := ye - ya;
x := xa; y := ya; setpixel( fehler := dx/2;
while x < 423 do begin x := x+1; fehler := fehler - dy; if fehler < 0 then begin y := y + 1; fehler := fehler + dx end; setpixel (x,y,clblack); end; end;
procedure TForm1.Button2Click(Sender: TObject); var xa,xe, ya, ye, x, y, i : integer; begin with form1.bild.Canvas do begin xa := 0; ya := 0; xe := bild.width; ye := bild.height; x := 8; y := 8;
Rectangle(0,0,bild.Width,Bild.Height); while y < Bild.Height do begin moveto(xa,y); lineto(xe,y); y := y+8; end; while x < Bild.Width do begin moveto(x,ya); lineto(x,ye); x := x+8; end; for i := 51 to 313 do p_figur (141,i); for i := 141 to 470 do p_figur (i,313); for i := 313 downto 220 do p_figur (470,i); for i := 470 downto 245 do p_figur (i,220); for i := 220 downto 51 do p_figur (245,i); for i := 245 downto 141 do p_figur (i,51); for i := 141 to 245 do p_figur (i,130); p_brese(330,423,220,313); end; end; end. |
"[Fehler]Unit1.pas(55): Nicht genügend wirkliche Parameter" und
"[Fehler]Unit1.pas(64): Nicht genügend wirkliche Parameter
Flamefire - Di 05.01.10 20:39
ich glaube dc ist das handle der bitmap. also bitmap.handle
oder es gibt direkt ein bitmap.dc
probiers aus ^^
alternativ: bitmap.pixels[x,y]:=clBlack; (oder bitmap.canves.pixels hab grad kein delphi da)
roKR-91 - Di 05.01.10 20:58
super...habs jetz hinbekommen...soll heißen er zeichnet jetz eine dünne linie...muss da jetz bloß noch n bissl mit floodfill rumexperimentieren und dann passt das schon...danke jungs...vorallem dir flamefire :)
roKR-91 - Mi 06.01.10 21:42
kann mir mal bitte jmd den post von ene erklären??? was soll das "raster" da sein ???? da blick ich nich durch...außerdem...warum geht das nich? :
Delphi-Quelltext
1: 2: 3: 4: 5:
| begin if form1.bild.Canvas.Pixels[x,y] = clwhite then repeat Floodfill(x,y,clblack,fsBorder); x := x+8; until form1.bild.Canvas.Pixels[x,y]= clblack; |
der meckert bei der zeile mit dem floodfill rum..."inkompatible typen: 'Cardinal' und 'TFillStyle' "
weiter oben hab ich die zeile mit dem floodfill genau so stehen und da geht...und funzt auch im programm
Flamefire - Mi 06.01.10 22:23
"Raster ist einfach die pixelmatrix. in dem fall also die "pixels" eigenschaft.
als erstes würde ich floodfill in eine neue zeile schreiben
wie sieht denn die deklaration von floodfill und fsBorder aus? ich vermute da stimmt was nicht.
oder die argumente vertauscht.
roKR-91 - Do 07.01.10 09:01
also mit dem floodfil geht jetz...es fehlte das "form1.bild.canvas." und dann einfach floodfill(x,y,clblack,fsborder)
roKR-91 - Di 09.02.10 00:14
ich weiß nich woran es liegt...kriegs einfach nich hin...sitz da jetz bestimmt schon 5-6 stunden dran...es will einfach nich...soweit bin ich bis jetz gekommen
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| procedure p_flood4 (x,y : integer); var dx, dy : integer; begin dx := form1.UpDown1.position + 8; dy := form1.UpDown1.position + 8;
if form1.bild.Canvas.Pixels[x,y] = clwhite then begin form1.bild.Canvas.brush.color := clblack; form1.bild.Canvas.Floodfill(x,y,clblack,fsBorder); repeat begin p_flood4[x+dx, y]; p_flood4[x-dx, y]; p_flood4[x, y+dy]; p_flood4[x, y-dy] end; until form1.bild.Canvas.Pixels[x,y]= clblack; end; end; |
prozeduraufruf sieht so aus
die zeilen
p_flood4[x+dx, y];
p_flood4[x-dx, y];
p_flood4[x, y+dy];
p_flood4[x, y-dy]
bemängelt er das er nich genügend parameter hat...ich weiß echt nichmehr was er von mir will...eig dachte ich das ich das so rekursiv geschrieben hab...aber es klappt einfach nich... -.-
wenn ihr noch nähere infos braucht fragt einfach...ich werd euch gern mein projekt näher bringen...
platzwart - Di 09.02.10 00:25
( anstatt [ verwenden...
roKR-91 - Di 09.02.10 13:22
lol...tatsächlich...son scheiß :D immer solche kleinigkeiten...ohoh...schlimm schlim...dank dir
roKR-91 - Do 11.03.10 18:51
hey ich hab nochmal ne schönheits frage zum floodfill...also das funzt bei mir jetz vollständig...hab jetz auch mit einer pause zwischen den schritten gearbeitet um das etwas anschaulicher zu machen...jetz fehlt nur noch das sahnehäubchen.
und zwar hab ich mir überlegt das es doch schön wäre wenn der pixel (bzw. das kästchen) wo sich der algorithmus grade befindet in einer anderen farbe dargestellt wird...wollte das so machen das der 2x floodfill ausführt (das zweite zeitversetzt)...und das dann übereinander zeichnet...somit wäre das erste kästchen sagen wir mal hellblau und die anderen dunkelblau...wo muss ich dann den 2ten lauf des floodfill hinschreiben ???
hier mal mein floodfill mir 4er nachbarschaft:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
| procedure p_flood4 (x,y : integer); var dx, dy : integer; begin dx := form1.UpDown1.position + 8; dy := form1.UpDown1.position + 8;
if form1.bild.Canvas.Pixels[x,y] = clwhite then begin form1.bild.Canvas.brush.color := claqua; form1.bild.Canvas.Floodfill(x,y,clblack,fsBorder); repeat begin p_pause(30); p_flood4(x+dx, y); p_pause(30); p_flood4(x-dx, y); p_pause(30); p_flood4(x, y+dy); p_pause(30); p_flood4(x, y-dy); p_pause(30); end; until form1.bild.Canvas.Pixels[x,y]= claqua; end; end; |
platzwart - Do 11.03.10 19:03
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
| procedure p_flood4 (x,y : integer); var dx, dy : integer; begin dx := form1.UpDown1.position + 8; dy := form1.UpDown1.position + 8;
if form1.bild.Canvas.Pixels[x,y] = clwhite then begin form1.bild.Canvas.brush.color := claqua; form1.bild.Canvas.Floodfill(x,y,clblack,fsBorder); p_pause(30); form1.bild.Canvas.brush.color := clRed; form1.bild.Canvas.Floodfill(x,y,clblack,fsBorder); p_pause(30); form1.bild.Canvas.brush.color := claqua; form1.bild.Canvas.Floodfill(x,y,clblack,fsBorder); p_pause(30); repeat begin p_pause(30); p_flood4(x+dx, y); p_pause(30); p_flood4(x-dx, y); p_pause(30); p_flood4(x, y+dy); p_pause(30); p_flood4(x, y-dy); p_pause(30); end; until form1.bild.Canvas.Pixels[x,y]= claqua; end; end; |
Vielleicht so probieren? Dann blinkt der Pixel einmal Rot...
roKR-91 - Do 11.03.10 21:14
hey das is soweit schonmal sehr gut...danke...nur leider sieht man es nich mehr blinken wenn er das 2te mal über ein kästchen geht...aber sonst is das schonmal so wie ich mir das gedacht hab
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!