Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Graswachstum


FinnO - Mi 25.02.09 18:40
Titel: Graswachstum
Hi leute!

Ich hab hier mal was richtig schönes für euch, das sozusagen suboptimalste der Welt...

Das Programm soll Rasenflächen auf dem Canvas vergrößern. Diese Flächen sind clGreen dargestellt.



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:
  TiMove.Enabled := False;
  Turtle.Canvas.Pen.Color := ClLime;
  Turtle.Canvas.Brush.Color := ClLime;

  for i := 1 to 1284 do
    for j := 0 to 800 do
      begin
        if Turtle.Canvas.Pixels[j,i] = clLime then
          Turtle.Canvas.Pixels[j,i] := clGreen;
      end;

  for i := 1 to 1284 do
    for j := 0 to 800 do
      begin

        if Turtle.Canvas.Pixels[j,i] = clGreen then
          begin
            Turtle.Canvas.Ellipse(j-10,i-10,j+10,i+10);
          end;
      end;

  for i := 1 to 1284 do
    for j := 0 to 800 do
      begin
        if Turtle.Canvas.Pixels[j,i] = clLime then
          Turtle.Canvas.Pixels[j,i] := clGreen;
      end;
  TiMove.Enabled := true;


ich glaub, das größte Problem ist die KOntrolle jedes einzelnen Pixels. Ich hab da mal was von "ScanLine" o.ä. gehört, gehtsdas so schneller?


jaenicke - Mi 25.02.09 18:46

Google kennst du aber? :lol:
Suche bei Google DELPHI SCANLINE
Bringt doch jede Menge Ergebnisse, das hier gleich als erstes: ;-)
http://www.efg2.com/Lab/ImageProcessing/Scanline.htm


FinnO - Do 26.02.09 18:04

hmm.. ich wäre sehr über allgemeine Vorschläge zur optimierung erfreut...


jaenicke - Do 26.02.09 18:19

Wenn du in allen drei Fällen Scanline benutzt wie in dem Link, dann sollte das doch schon extrem viel schneller sein. :gruebel:


GTA-Place - Do 26.02.09 18:23

Wenn du sowieso alles in der letzten Schleife wieder grün machst, warum machst du dann die Kreise nicht auch gleich in Grün?


FinnO - Do 26.02.09 18:41

aus dem Einfachen Grund, dass die Grünen Flecken dann als "altes" Gras empfunden werden, und die Grasfläche extrem anwächst.


jaenicke - Do 26.02.09 18:52

Dann schauen wir doch einmal was du machst:
Erst färbst du alle Pixel mit clLime in clGreen um. Dann zeichnest du an allen Pixeln mit clGreen einen Kreis in der Farbe clLime. Und am Ende färbst du genau alle diese gerade gezeichneten Pixel clGreen...

Du könntest also den Kreis auch gleich mit clGreen zeichnen, es macht exakt gar keinen Unterschied im Ablauf.

Beim nächsten Durchlauf, falls es einen gibt, durchläufst du wieder die erste Schleife. Es kann aber gar keine Pixel mehr geben, die die Farbe clLime haben, denn die hast du ja clGreen gefärbt. Und die werden auch sämtlich alle jetzt mit Kreisen übermalt.


FinnO - Do 26.02.09 19:16

dein Fehler ist:

Wenn ich alle Felder sofort ClGreen einfärbe, dann sieht das so aus:

Feld 100,100 ist grün und von weißen pixeln umrandet
Man malt auf Feld 100,100 einen großen Grünen klecks
Feld 101,100 ist plötzlich auch grün
auch hier wird ein Klecks gemalt -> Unendlich große Farbfläche

und es kann sehr wohl clLime farbene Felder geben, weil die oberhalb von dem in der zweiten schleife eingefärbten Felder nicht korrigiert werden.


jaenicke - Do 26.02.09 19:20

user profile iconFinnO hat folgendes geschrieben Zum zitierten Posting springen:
und es kann sehr wohl clLime farbene Felder geben, weil die oberhalb von dem in der zweiten schleife eingefärbten Felder nicht korrigiert werden.
Aber du änderst doch die Farbe restlos aller Pixel mit der Farbe clLime in clGreen, wie können da welche in clLime übrigbleiben? :shock:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
for i := 1 to 1284 do
    for j := 0 to 800 do
      begin
        if Turtle.Canvas.Pixels[j,i] = clLime then
          Turtle.Canvas.Pixels[j,i] := clGreen;
      end;
  TiMove.Enabled := true;


FinnO - Do 26.02.09 19:47

die schleife läuft aber erst nach dem Wachsen an... ich mach dir mal screenshots - moment

Edit:

:shock: ich hab ja noch den alten Code hier stehen :P dann ist das ja auch kein wunder, wenn wir aneinander vorbeireden...


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
  for i := 1 to 800 do
    for j := (((TiGras.Tag-1)*50)-1to TiGras.Tag*50 do
      begin
        if Turtle.Canvas.Pixels[j,i] = $009900 then
          begin
            Turtle.Canvas.Ellipse(j-10,i-10,j+10,i+10);
          end;
        if Turtle.Canvas.Pixels[j,i] = $009800 then
          Turtle.Canvas.Pixels[j,i] := $009900;
      end;
  for i := 1 to 800 do
    for j := (((TiGras.Tag-1)*50)+1to TiGras.Tag*50 do
      begin
        if Turtle.Canvas.Pixels[j,i] = $009800 then
          Turtle.Canvas.Pixels[j,i] := $009900;
      end;


das Bild wird jetzt gerastert. Sorry ;)