Autor Beitrag
roKR-91
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: Do 10.12.09 21:37 
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 779
Erhaltene Danke: 1

Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
BeitragVerfasst: 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:

ausblenden 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  ]= 0Then FloodFill(X+1, Y  );
  If (Raster[x-1,y  ]= 0Then FloodFill(X-1, Y  );
  If (Raster[x  ,y+1]= 0Then FloodFill(X  , Y+1);
  If (Raster[x  ,y-1]= 0Then 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.

_________________
Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
roKR-91 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: 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...
Einloggen, um Attachments anzusehen!
ub60
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 764
Erhaltene Danke: 127



BeitragVerfasst: Di 05.01.10 18:36 
Da empfehle ich mal Bresenham de.wikipedia.org/wik...resenham-Algorithmus

ub60
roKR-91 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: Di 05.01.10 19:22 
so ich hab jetz den wiki-bresenham der in basic geschrieben war in delphi geschrieben
ausblenden 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 :

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: 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.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Di 05.01.10 19:40 
Damit die while-Schleife einen Sinn ergibt, dürfte da auch noch ein begin .. end hingehören.

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
roKR-91 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: 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...

ausblenden volle Höhe 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
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  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
  //zuweisen der Werte
  xa := 0;
  ya := 0;
  xe := bild.width;
  ye := bild.height;
  x := 8;
  y := 8;

  Rectangle(0,0,bild.Width,Bild.Height);
  //horizontale linien
  while y < Bild.Height do
    begin
      moveto(xa,y);
      lineto(xe,y);
      y := y+8;
     end// of while
  //vertikale linien
  while x < Bild.Width do
    begin
      moveto(x,ya);
      lineto(x,ye);
      x := x+8;
     end;//of while
    // FIGUR ZEICHNEN

  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);
  // begrenzungen innerhalb der figur
  for i := 141 to 245 do
    p_figur (i,130);
  p_brese(330,423,220,313);    // diagonale linie für 8er nachbarschaft

  end//of canvas

end;// of procedure

end.


"[Fehler]Unit1.pas(55): Nicht genügend wirkliche Parameter" und
"[Fehler]Unit1.pas(64): Nicht genügend wirkliche Parameter
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: 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? :
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: 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

ausblenden 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 und dy dem raster anpassen
  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// of repeat

   until form1.bild.Canvas.Pixels[x,y]= clblack;
  end;
end;//of procedure p_flood4


prozeduraufruf sieht so aus

ausblenden Delphi-Quelltext
1:
p_flood4(170,200);					



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
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1054
Erhaltene Danke: 78

Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
BeitragVerfasst: Di 09.02.10 00:25 
( anstatt [ verwenden...

_________________
Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
roKR-91 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: Di 09.02.10 13:22 
lol...tatsächlich...son scheiß :D immer solche kleinigkeiten...ohoh...schlimm schlim...dank dir
roKR-91 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: 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:

ausblenden 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 und dy dem raster anpassen
  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// of repeat

   until form1.bild.Canvas.Pixels[x,y]= claqua;
  end// of if
end;//of p_flood4
platzwart
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1054
Erhaltene Danke: 78

Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
BeitragVerfasst: Do 11.03.10 19:03 
ausblenden volle Höhe 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 und dy dem raster anpassen
  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// of repeat

   until form1.bild.Canvas.Pixels[x,y]= claqua;
  end// of if
end;//of p_flood4



Vielleicht so probieren? Dann blinkt der Pixel einmal Rot...

_________________
Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
roKR-91 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: 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