Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   if-Abfrage vereinfachen (https://www.delphipraxis.net/90017-if-abfrage-vereinfachen.html)

Luckie 10. Apr 2007 13:36


if-Abfrage vereinfachen
 
Ich habe hier eine ziemlich grausame if-Abfrage. Kann man die eventuell vereinfachen?
Delphi-Quellcode:
  if (Show and not FShowGrid) or (Show and FShowGrid) then
  begin
    FImageEnVect.Bitmap.Canvas.Pen.Mode := pmBlack;
  end
  else if (FShowGrid and not Show) or (not FShowGrid and not Show) then
  begin
    FImageEnVect.Bitmap.Canvas.Pen.Mode := pmNotXor;
  end;

Gruber_Hans_12345 10. Apr 2007 13:39

Re: if-Abfrage vereinfachen
 
ist doch :
Delphi-Quellcode:
if Show then
  begin
    FImageEnVect.Bitmap.Canvas.Pen.Mode := pmBlack;
  end
  else
  begin
    FImageEnVect.Bitmap.Canvas.Pen.Mode := pmNotXor;
  end;
... oder hab ich da was falsch interpretiert ?

andreash 10. Apr 2007 13:39

Re: if-Abfrage vereinfachen
 
Wie wäre es damit
Delphi-Quellcode:
if Show then
    FImageEnVect.Bitmap.Canvas.Pen.Mode := pmBlack
  else
    FImageEnVect.Bitmap.Canvas.Pen.Mode := pmNotXor;
Edit: Semikolon gelöscht :-)

TeronG 10. Apr 2007 13:42

Re: if-Abfrage vereinfachen
 
Zitat:

Zitat von Gruber_Hans_12345

... oder hab ich da was falsch interpretiert ?

würd ich auch so sehen ..
evtl sogar noch n tick kürzer:
Delphi-Quellcode:
if Show
  then FImageEnVect.Bitmap.Canvas.Pen.Mode := pmBlack;
  else FImageEnVect.Bitmap.Canvas.Pen.Mode := pmNotXor;
EDIT: zu langsam :/
EDIT2: Aber irgendwie verwundert mich diese Frage (von Luckie)

MathiasSimmack 10. Apr 2007 13:46

Re: if-Abfrage vereinfachen
 
Das spielt doch keine Rolle, ob du zu langsam warst oder nicht. Wichtig ist, dass es klappt. :thumb: Es ist zwar off-topic, aber wenn ich mir die Ausgangslage angucke und mit dem Ergebnis vergleiche ... :lol: ... ich sehe schon einen Artikel vor mir:
Zitat:

Ich programmiere schon länger und habe schon so manche Zeile an Code geschrieben und gelesen. Aber im Laufe seiner Laufbahn als Programmierer wird man immer wieder über ein Problem stolpern, welches einen dazu veranlasst wieder etwas dazu zu lernen, auch wenn es nur etwas Banales ist wie bool'sche Operationen [...]
:mrgreen:

Luckie 10. Apr 2007 13:47

Re: if-Abfrage vereinfachen
 
Zitat:

Zitat von Gruber_Hans_12345
ist doch :
Delphi-Quellcode:
if Show then
  begin
    FImageEnVect.Bitmap.Canvas.Pen.Mode := pmBlack;
  end
  else
  begin
    FImageEnVect.Bitmap.Canvas.Pen.Mode := pmNotXor;
  end;
... oder hab ich da was falsch interpretiert ?

So hatte ich es vorher auch, aber das hat irgendwie nicht das gemacht, was es sollte. Werde ich dann wohl noch mal probieren. :gruebel:

MathiasSimmack 10. Apr 2007 13:52

Re: if-Abfrage vereinfachen
 
Die Bedingung ist aber recht eindeutig, Micha:
Delphi-Quellcode:
if (Show and not FShowGrid) or (Show and FShowGrid) then
FShowGrid kann TRUE oder FALSE sein, Show ist dagegen immer TRUE. Und anders herum:
Delphi-Quellcode:
else if (FShowGrid and not Show) or (not FShowGrid and not Show)
Show ist grundsätzlich FALSE, und FShowGrid kann wieder TRUE oder FALSE sein. Wie du ja selbst gemerkt hast, kannst du die Bedingung auf Show kürzen und FShowGrid komplett wegfallen lassen. Es wäre dann natürlich interessant, ob das Fehlverhalten immer noch auftritt, und ob es überhaupt mit der Bedingung zu tun hat.

Gruber_Hans_12345 10. Apr 2007 13:53

Re: if-Abfrage vereinfachen
 
wäre sogar noch kürzer ;) (aber nicht wirklich gut lesbar ... )
Delphi-Quellcode:
FImageEnVect.Bitmap.Canvas.Pen.Mode := TPenMode(integer(not Show) * integer(pmNotXor));

MathiasSimmack 10. Apr 2007 13:57

Re: if-Abfrage vereinfachen
 
:thumb: Ich habe leider kein Delphi zum Prüfen, aber der numerische Wert von "pmBlack" ist dann wohl Null? Ja, ist er, wie eine Google-Suche zeigt. ;)

Luckie 10. Apr 2007 14:02

Re: if-Abfrage vereinfachen
 
Ok, hier mal die die vollständige Routine:
Delphi-Quellcode:
procedure TDWFotoBook.PaintGrid(Show: Boolean = True);

  procedure DrawDots;
  var
    i              : Integer;
    j              : Integer;
  begin
    with FImageEnVect do
    begin
      // draw dots
      for i := 0 to Width div FGridWidth do
      begin
        for j := 0 to Height div FGridWidth do
        begin
          Bitmap.Canvas.Pixels[i * FGridWidth, j * FGridWidth] := clBlack;
        end;
      end;
      Update;
    end;
  end;

begin
  Assert(Assigned(ImageEnVect), IENIL);
  // deselect all layers, otherwise we would draw on the selected layer
  FImageEnVect.LayersCurrent := 0;
  // set pen mode
  if (Show and not FShowGrid) or (Show and FShowGrid) then
  begin
    FImageEnVect.Bitmap.Canvas.Pen.Mode := pmBlack;
  end
  else if (FShowGrid and not Show) or (not FShowGrid and not Show) then
  begin
    FImageEnVect.Bitmap.Canvas.Pen.Mode := pmNotXor;
  end;

  DrawDots;

  Self.FShowGrid := Show;
end;

Gruber_Hans_12345 10. Apr 2007 14:04

Re: if-Abfrage vereinfachen
 
Zitat:

Zitat von MathiasSimmack
:thumb: Ich habe leider kein Delphi zum Prüfen, aber der numerische Wert von "pmBlack" ist dann wohl Null?

ja ist 0 ... ansonsten
Delphi-Quellcode:
FImageEnVect.Bitmap.Canvas.Pen.Mode := TPenMode(integer((not Show)) * (integer(pmNotXor) - integer(pmBlack)) + integer(pmBlack));

Gruber_Hans_12345 10. Apr 2007 14:08

Re: if-Abfrage vereinfachen
 
verwendet pixels überhaupt den PenMode? ... mal googeln

[edit]ok, verwendets


Aber mal eine andere Frage, was sollte den die Funktion genau machen?
du zeichnest einmal direkt schwarz drauf und einmal mit XOR ... ist irgendwie unlogisch für mich, entweder immer per schwarz, wenn das raster auf eine leere fläche gezeichnet wird, oder immer per XOR, wenn das raster über bestehende Grafik gezeichnet wird, und mit einem 2ten xor dann wieder wegmalen das Raster.

Robert Marquardt 10. Apr 2007 14:16

Re: if-Abfrage vereinfachen
 
Ein bischen OT, aber die Funktion ist falsch unterteilt.
DrawDots sollte nicht in eine lokale Funktion ausgelagert werden, da es ja das eigentliche Herzstueck der Methode ist.
Der Pen.Mode hat uebrigens nicht den geringsten Einfluss auf das Setzen der Pixel. Der Pen ist fuer das Zeichnen von Linien verantwortlich.
Was soll uebrigens das Update bewirken? Ist hier das TDWFotoBook.Update gemeint oder FImageEnVect.Update?
Schmeiss das with raus, da es nur Probleme bereitet, aber nicht zur Lesbarkeit beitraegt.

Nachgeprueft an der TCanvas-Implementierung: Es wird Windows.SetPixel aufgerufen das nach Windows-Hilfe keinen Pen.Mode beruecksichtigt.

Christian Seehase 10. Apr 2007 14:16

Re: if-Abfrage vereinfachen
 
Moin Michael,

also ich würde die "Abfrage" so machen:

Delphi-Quellcode:
const
  _aPenMode : array [boolean] of TPenMode = (pmNotXor,pmBlack);

FImageEnVect.Bitmap.Canvas.Pen.Mode := _aPenMode[FShow];

MathiasSimmack 10. Apr 2007 14:20

Re: if-Abfrage vereinfachen
 
;) Erinnert mich daran, dass ich solche bool'schen Arrays immer gern eingesetzt habe, weil ich auf die C-Variante
Code:
Pen.Mode = (Show)?pmBlack:pmNotXor; // fiktiver Code
neidisch war. Ich glaube, der Gedanke mit dem Array kam von Hagen. Die Variante hätte den Vorteil, dass man anstelle von "pmBlack" auch was anderes nehmen könnte. Diese Sache hier ist nämlich auch klasse, funktioniert aber eben bloß mit pmBlack (= Null) und einem anderen Wert.

Gruber_Hans_12345 10. Apr 2007 14:20

Re: if-Abfrage vereinfachen
 
Zitat:

Zitat von Robert Marquardt
Der Pen.Mode hat uebrigens nicht den geringsten Einfluss auf das Setzen der Pixel. Der Pen ist fuer das Zeichnen von Linien verantwortlich.

sicher? - ich habs getestet und der pen.mode ist sehr wohl auch für das SetPixel zuständig

Robert Marquardt 10. Apr 2007 14:28

Re: if-Abfrage vereinfachen
 
Eigentlich ja. Ich kann mir nicht vorstellen das Microsoft das zu dokumentieren vergessen haette wenn der Mode Einfluss auf SetPixel haette.
Es macht ja auch keinen Sinn, da der Pen nur zum Zeichnen von Linien zustaendig ist.

Luckie 10. Apr 2007 14:38

Re: if-Abfrage vereinfachen
 
Wenn TPen.Mode keinen Einfluss auf SetPixel hat, warum werden sie dann einmal gemalt und einmal nicht?

Sinn ist der: Ich habe ein Grid zum Ausrichten von Objekten. Dieses soll man anzeigen und nicht nazeigen können. Wenn es angezeigt wird, muss ich es eben entsprechend übermalen, um es wieder verschwiden zu lassen. Dabei kann der Hintergrund jede beliebige Frabe an jeder beliebigen Stelle haben.

Gruber_Hans_12345 10. Apr 2007 14:58

Re: if-Abfrage vereinfachen
 
Zitat:

Zitat von Luckie
Wenn TPen.Mode keinen Einfluss auf SetPixel hat, warum werden sie dann einmal gemalt und einmal nicht?

Sinn ist der: Ich habe ein Grid zum Ausrichten von Objekten. Dieses soll man anzeigen und nicht nazeigen können. Wenn es angezeigt wird, muss ich es eben entsprechend übermalen, um es wieder verschwiden zu lassen. Dabei kann der Hintergrund jede beliebige Frabe an jeder beliebigen Stelle haben.

um es verschwinden zu lassen, braucht man normalerweise ja nur ein zweites mal mit der selben farbe mit xor drübermalen
also erstes mal mit clBlack und Xor malen -> Grid ist da, zweites mal mit clBlack und Xor malen -> Grid ist weg, das wäre ja der sinn von den xor sachen beim malen.

@Robert: ich war auch der meinung, das es keinen einfluß hat, und auch wenns ms nicht dokumentiert hat, es hat einen einfluß, habs extra vorher noch getestet.

Robert Marquardt 10. Apr 2007 15:17

Re: if-Abfrage vereinfachen
 
pmBlack ist Unsinn. Es bedeutet das immer mit Schwarz gemalt wird, egal was fuer eine Farbe man nimmt. Bitte ausprobieren ob mit einer anderen Farbe als clBlack die andere Farbe benutzt wird oder Schwarz. Andere Farbe heisst das der Pen.Mode keinen Einfluss hat.

Gruber_Hans_12345 10. Apr 2007 15:39

Re: if-Abfrage vereinfachen
 
Zitat:

Zitat von Robert Marquardt
pmBlack ist Unsinn. Es bedeutet das immer mit Schwarz gemalt wird, egal was fuer eine Farbe man nimmt. Bitte ausprobieren ob mit einer anderen Farbe als clBlack die andere Farbe benutzt wird oder Schwarz. Andere Farbe heisst das der Pen.Mode keinen Einfluss hat.

dann probier es einfach selbst aus :
Delphi-Quellcode:
    image1.Picture.Bitmap.Width := 200;
    image1.Picture.Bitmap.Height := 200;
    image1.Picture.Bitmap.Canvas.Pen.Color := clRed;
    image1.Picture.Bitmap.Canvas.MoveTo(0, 0);
    image1.Picture.Bitmap.Canvas.LineTo(100, 100);
    image1.Picture.Bitmap.Canvas.Pen.Mode  := pmXor;
    for x:=1 to 100 do
        for y := 1 to 100 do
            image1.Picture.Bitmap.Canvas.Pixels[x, y] := clGreen;

Pen.Mode hat den einfluß, das wenn man pmBlack verwendet schwarz gemalt wird egal welche farbe man beim Pixel angibt, bei pmXor wird gexort mit der farbe usw. ... im prinzip könnte man es auch so ausdrücken, das beim setzen eines pixel mit SetPixel der Pen.Mode berücksichtigt wird ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:15 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz