![]() |
Zeichnen auf Canvas und ZOrder bzw. Übermalen
Kennt der Canvas beim zeichnen keine ZOrder?
Jetzt zeichne ich schon auf ein Bitmap und ist immer noch Müll! Ich zeichne alles in der richtigen Reihenfolge trotzdem sind die Linien über den Kreisen und nicht drunter.
Delphi-Quellcode:
gruss
procedure TGraph.Draw;
begin Bitmap.Canvas.Font.Color := clblack; Bitmap.Canvas.Pen.Width := 1; PrepareScale; If Physics.D <> 0 then begin // Linie an der das Pendel (Ball) hängt Bitmap.Canvas.Pen.Color := clblack; Bitmap.Canvas.MoveTo(xxc(Physics.x0), yyc(Physics.y0)); Bitmap.Canvas.LineTo(xxc(Physics.x1), yyc(Physics.y1)); end; Bitmap.Canvas.Brush.Style:= bsSolid; Bitmap.Canvas.brush.Color := clblack; Bitmap.Canvas.Pen.Width := 5; // Center Punkt DrawEllipseFromCenter(Bitmap.Canvas, xxc(Physics.x0), yyc(Physics.y0), round(Physics.r0 * xFact)); // Ball Bitmap.Canvas.brush.Color := clred; Bitmap.Canvas.Pen.Width := 2; DrawEllipseFromCenter(Bitmap.Canvas, xxc(Physics.x1), yyc(Physics.y1), round(Physics.r1 * xFact)); // vom Bitmap auf das Canvas kopieren BitBlt(PaintFrame.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height, Bitmap.Canvas.Handle, 0, 0, srccopy); end; |
AW: Zeichnen auf Canvas und ZOrder
Nein, natürlich nicht.
Wozu sollte eine 2-dimensionale Zeichenfläche (wie ein Blatt Papier) eine dritte Dimension behandeln? Und wenn doch, warum dann nicht auch die Vierte, Fünfte und Sechste? Wer zuletzt malt, der malt zuletzt, aber hab jetzt keine Ahnung was DrawEllipseFromCenter macht. Die übermalten Bälle sind nicht zufällig Bälle, die schon vor Aufruf der Draw-Funktion auf dem Bitmap drauf sind? :stupid: |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Zitat:
Warum sollten Sie? Und zufällig schon gar nicht. Wie du im Code ersehen kannst.
Delphi-Quellcode:
DrawEllipseFromCenter(Bitmap.Canvas, xxc(Physics.x1), yyc(Physics.y1), round(Physics.r1 * xFact));
Dabei ist es uninteressant was DrawEllipseFromCenter macht. Wenn ich eine Linie zeichne und anschließend einen Ball, auf dem die Linie zur hälft liegt (Normaler weise dahinter) Dann sollte die Linie eigentlich nicht sichtbar sein Oder? Denn schließlich zeichne ich die Linie zuerst.
Delphi-Quellcode:
Bitmap.Canvas.brush.Color := clred;
Ist die Farbe vielleicht Transparent und nicht deckend so das man die Linie noch sieht? Wobei wie man sehen kann der Style Solid ist
Delphi-Quellcode:
Bitmap.Canvas.Brush.Style:= bsSolid;
Zitat:
Sieh Bild. Alle Linien müssten eigentlich unsichtbar sein innerhalb des roten Ball's da dieser zuletzt gezeichnet wird. gruss |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Hast du mal Pen.Mode mal eingestellt?
Delphi-Quellcode:
begin
with canvas do begin Pen.Width := 5; Pen.Mode := pmMergePenNot; //<<<--- Brush.Color := clRed; Brush.Style := bsSolid; MoveTo(0, 0); LineTo(200, 200); Ellipse(0, 0, 200, 200); end; end; |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Zitat:
Habe es jetzt auf GDI+ umgestellt.
Delphi-Quellcode:
Damit geht es wie es soll.. Qualität siehe Anhang.
procedure TGraph.Draw;
begin PrepareScale; graphics := TGPGraphics.Create(Bitmap.Canvas.Handle); graphics.SetSmoothingMode(SmoothingModeAntiAlias); Pen := TGPPen.Create(MakeColor(255, 0, 0, 0)); path := TGPGraphicsPath.Create; brush := TGPSolidBrush.Create(MakeColor(255, 0, 0, 0)); // Pendel Linie If Physics.D <> 0 then graphics.DrawLine(Pen, xxc(Physics.x0), yyc(Physics.y0), xxc(Physics.x1), yyc(Physics.y1)); // Pendel Center Punkt DrawEllipseFromCenter(path, xxc(Physics.x0), yyc(Physics.y0), round(Physics.r0 * xFact)); graphics.DrawPath(pen, path); graphics.FillPath(brush, path); // Pendel (Ball) path.Reset; Pen.SetColor(MakeColor(255, 0, 0, 0)); brush.SetColor(MakeColor(255, 255, 0, 0)); DrawEllipseFromCenter(path, xxc(Physics.x1), yyc(Physics.y1), round(Physics.r1 * xFact)); graphics.DrawPath(pen, path); graphics.FillPath(brush, path); // vom Bitmap auf das Canvas kopieren BitBlt(PaintFrame.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height, Bitmap.Canvas.Handle, 0, 0, srccopy); Pen.Free; path.Free; brush.Free; graphics.Free; end; Danke! gruss |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Mit
Delphi-Quellcode:
FImage.Canvas.Pen.Mode := pmMergePenNot;
Sehe ich jetzt nicht mehr den Hintergrund (Linie) vom Grauen Kreis. Aber immer noch die Linie auf dem Ball.
Delphi-Quellcode:
gruss
procedure TGraph.Draw;
begin FImage.Canvas.Font.Color := clblack; FImage.Canvas.Pen.Mode := pmMergePenNot; PrepareScale; // Die Linie ist noch auf dem Ball sichtbar. If Physics.D <> 0 then begin FImage.Canvas.Pen.Color := clblack; FImage.Canvas.MoveTo(xxc(Physics.x0), yyc(Physics.y0)); FImage.Canvas.LineTo(xxc(Physics.x1), yyc(Physics.y1)); end; FImage.Canvas.Brush.Style:= bsSolid; FImage.Canvas.brush.Color := clblack; FImage.Canvas.Pen.Width := 5; DrawEllipseFromCenter(FImage.Canvas, xxc(Physics.x0), yyc(Physics.y0), round(Physics.r0 * xFact)); FImage.Canvas.brush.Color := clred; FImage.Canvas.Pen.Width := 2; DrawEllipseFromCenter(FImage.Canvas, xxc(Physics.x1), yyc(Physics.y1), round(Physics.r1 * xFact)); FImage.Canvas.Pen.Width := 1; end; |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Zitat:
Zitat:
|
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Zitat:
Dort wird nur der Mittelpunkt ermittelt und Ellipse(R) ausgeführt nicht mehr. Alles andere ist in Draw. Die zeichnen Operationen sind bereits schon in Draw festgelegt bevor ich den Ball Zeichne.
Delphi-Quellcode:
gruss
FImage.Canvas.brush.Color := clred;
FImage.Canvas.Pen.Width := 2; |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Zitat:
Da in der Draw keine Kreise gezeichnet werden, müssen diese ja in "DrawEllipseFromCenter" gezeichnet werden. Und da Du uns diese verheimlichst können wir auch nicht sehen, was darin oder was nicht passiert. |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Zitat:
Wenn ich sage es ist uninteressant das ist das so.. und fertig. Wie lange wollen wir jetzt darüber debattieren. Es steht in keinen Bezug zu meinem Problem. Wenn ich eine Linie zeichne und einen Kreis darüber lege sollte die Linie überdeckt werden. Geht wohl nicht mit Boardmitteln daher bin ich auf GDI+ ausgewichen. Hat sich also erledigt. gruss |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Zitat:
Zitat:
|
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Zitat:
Zitat:
gruss |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Zitat:
Delphi-Quellcode:
Der Kreis liegt über der Linie und die Linie ist definitiv nicht im Bereich des Kreises sichtbar, sondern wird komplett verdeckt.
procedure TForm1.Button1Click(Sender: TObject);
begin Image1.Canvas.Font.Color := clblack; Image1.Canvas.Pen.Color := clblack; Image1.Canvas.MoveTo(0,0); Image1.Canvas.LineTo(100,100); Image1.Canvas.Brush.Style:= bsSolid; Image1.Canvas.Brush.Color := clLime; Image1.Canvas.Pen.Width := 5; Image1.Canvas.Ellipse(30,30,70,70); end; Also doch ein moglicher Fehler in DrawEllipseFromCenter. |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Zitat:
Delphi-Quellcode:
Fehler? LOL
procedure TGraph.DrawEllipseFromCenter(Canvas: TCanvas; XOffset: integer;
YOffset: integer; RadiusOfCircle: Integer); Var R: TRect; begin R.Top := YOffset - RadiusOfCircle; R.Left := XOffset - RadiusOfCircle; R.Bottom := YOffset + RadiusOfCircle; R.Right := XOffset + RadiusOfCircle; Canvas.Ellipse(R); end; gruss |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Hallo Emil, wer zuletzt malt malt zuletzt, das trifft auch für Brush.Style zu (Siehe Setter von TBrush). :wink:
Delphi-Quellcode:
Color und Style beeinflussen sich auch gegenseitig.
// ergibt bsClear;
Bitmap.Canvas.Brush.Color := clInfoBK; Bitmap.Canvas.Brush.Style := bsClear; // ergibt bsSolid; Bitmap.Canvas.Brush.Style := bsClear; Bitmap.Canvas.Brush.Color := clInfoBK; // *** |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Zitat:
Verstehe aber nicht wo ich es einsetzen soll. Funktioniert einfach nicht. Zuerst wird PrepareScale aufgerufen aus der Draw function.
Delphi-Quellcode:
dann die Draw selbst.
procedure TGraph.PrepareScale;
var gray: Integer; begin If ScaleMax = 0 Then ScaleMax := 1; Aspect := Bitmap.Width / Bitmap.Height; yMin := -ScaleMax; yMax := ScaleMax; xMin := -ScaleMax * Aspect; xMax := ScaleMax * Aspect; Bo := 20; BoLeft := Bo; BoTop := Bo; BoRight := Bo; BoBottom := Bo; Fact; Bitmap.Canvas.brush.Color := $00E0FFFF; // Hintergrund löschen Bitmap.Canvas.FillRect(Bitmap.Canvas.ClipRect); if HelpIsOn then DrawHelp; gray := 200; gray := RGB(gray, gray, gray); Bitmap.Canvas.Pen.Color := gray; // Koordinatenkreuz Bitmap.Canvas.MoveTo(xxc(xMin), yyc(0)); Bitmap.Canvas.LineTo(xxc(xMax), yyc(0)); Bitmap.Canvas.MoveTo(xxc(0), yyc(yMin)); Bitmap.Canvas.LineTo(xxc(0), yyc(yMax)); // Brush löschen Bitmap.Canvas.Brush.Style:= bsClear; // Kreis zeichnen DrawEllipseFromCenter(Bitmap.Canvas, xxc(Physics.x0), yyc(Physics.y0), trunc(xFact * Physics.L0)); Bitmap.Canvas.Pen.Color := clblack; //Rechteck von links oben nach rechts unten Bitmap.Canvas.Rectangle(xxc(xMin), yyc(yMin), xxc(xMax), yyc(yMax)); end;
Delphi-Quellcode:
procedure TGraph.Draw;
begin Bitmap.Canvas.Font.Color := clblack; PrepareScale; // Pendel Linie If Physics.D <> 0 then begin Bitmap.Canvas.Pen.Color := clblack; Bitmap.Canvas.MoveTo(xxc(Physics.x0), yyc(Physics.y0)); Bitmap.Canvas.LineTo(xxc(Physics.x1), yyc(Physics.y1)); end; // Pendel Center Punkt Bitmap.Canvas.Brush.Style:= bsclear; Bitmap.Canvas.Pen.Width := 3; Bitmap.Canvas.Pen.Mode := pmMergePenNot; DrawEllipseFromCenter(Bitmap.Canvas, xxc(Physics.x0), yyc(Physics.y0), round(Physics.r0 * xFact)); // Pendel (Ball) Bitmap.Canvas.brush.Color := clred; Bitmap.Canvas.Pen.Width := 2; DrawEllipseFromCenter(Bitmap.Canvas, xxc(Physics.x1), yyc(Physics.y1), round(Physics.r1 * xFact)); Bitmap.Canvas.Pen.Width := 1; // vom Bitmap auf das Canvas kopieren BitBlt(PaintFrame.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height, Bitmap.Canvas.Handle, 0, 0, srccopy); end; pmMergeNotPen > Combination of canvas background color and inverse of pen Color. Sorgt dafür das der gro0e Graue Kreis überdeckt wird. Was soll da falsch sein (oder vergessen) das es nicht geht. gruss |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Zitat:
Delphi-Quellcode:
(PaintFrame ist dabei eine TPaintBox) Also irgendwie zeigst du uns nicht das Relevante. :-)
procedure DrawEllipseFromCenter(Canvas: TCanvas; XOffset: integer; YOffset: integer; RadiusOfCircle: Integer);
var R: TRect; begin R.Top := YOffset - RadiusOfCircle; R.Left := XOffset - RadiusOfCircle; R.Bottom := YOffset + RadiusOfCircle; R.Right := XOffset + RadiusOfCircle; Canvas.Ellipse(R); end; procedure TForm2.PaintFramePaint(Sender: TObject); var Bitmap: TBitmap; const Physics_x0 = 100; Physics_x1 = 200; Physics_y0 = 100; Physics_y1 = 200; Physics_r0 = 30; Physics_r1 = 40; xFact = 1; function xxc(x: Integer): Integer; begin Result := x; end; function yyc(y: Integer): Integer; begin Result := y; end; begin Bitmap := TBitmap.Create; try Bitmap.SetSize(PaintFrame.ClientWidth, PaintFrame.ClientHeight); Bitmap.Canvas.Font.Color := clblack; Bitmap.Canvas.Pen.Width := 1; //PrepareScale; // Linie an der das Pendel (Ball) hängt Bitmap.Canvas.Pen.Color := clblack; Bitmap.Canvas.MoveTo(xxc(Physics_x0), yyc(Physics_y0)); Bitmap.Canvas.LineTo(xxc(Physics_x1), yyc(Physics_y1)); Bitmap.Canvas.Brush.Style := bsSolid; Bitmap.Canvas.brush.Color := clblack; Bitmap.Canvas.Pen.Width := 5; // Center Punkt DrawEllipseFromCenter(Bitmap.Canvas, xxc(Physics_x0), yyc(Physics_y0), round(Physics_r0 * xFact)); // Ball Bitmap.Canvas.brush.Color := clred; Bitmap.Canvas.Pen.Width := 2; DrawEllipseFromCenter(Bitmap.Canvas, xxc(Physics_x1), yyc(Physics_y1), round(Physics_r1 * xFact)); // vom Bitmap auf das Canvas kopieren BitBlt(PaintFrame.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height, Bitmap.Canvas.Handle, 0, 0, srccopy); finally Bitmap.Free; end; end; |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Zitat:
gruss |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Zitat:
Bei deiner Skizze sieht es ja so aus als ob der Kreis quasi mit bsClear gezeichnet wäre? Lass mal den Pen.Mode weg.
Delphi-Quellcode:
procedure TBrush.SetColor(Value: TColor);
var BrushData: TBrushData; begin if (Value <> Color) or ((Style = bsClear) and (Style <> bsSolid)) then begin GetData(BrushData); BrushData.Color := Value; if BrushData.Style = bsClear then BrushData.Style := bsSolid; SetData(BrushData); end; end; procedure TBrush.SetStyle(Value: TBrushStyle); var BrushData: TBrushData; begin if (Value <> Style) or ((Value = bsClear) and (Color <> clWhite)) then begin GetData(BrushData); BrushData.Style := Value; if BrushData.Style = bsClear then BrushData.Color := clWhite; SetData(BrushData); end; end; |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Hallo Bjoerk
Zitat:
Jetzt funktioniert es. Aber würde mich trotzdem nochmal interessieren warum Pen.Mode und bsClear sich im Wege stehen (für spätere Projekte). Danke schön.. Jetzt kann ich 2 Projekte hochladen einmal mit GDI und einmal GDI+ So kann man das mal vergleichen. gruss |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Zitat:
Der Bösewicht findet sich in der Prozedur PrepareScale:
Delphi-Quellcode:
Einmal eingestellt beleibt es über Prozeduren bestehen.
procedure TGraph.PrepareScale;
var gray: Integer; begin ... // Koordinatenkreuz Image.Canvas.Pen.Mode := pmNotXor; //<<<--- hier Image.Canvas.MoveTo(xxc(xMin), yyc(0)); Image.Canvas.LineTo(xxc(xMax), yyc(0)); ... //EDIT: Sorry, hab deinen letzten Beitrag #20 vor meinem Beitrag nicht gelesen. Anscheinend hast du schon selbst das Problem gefunden. Zitat:
Also, Pen.Mode hat mit bsClear nichts zu tun. |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Einmal am Canvas zuviel rumgespielt und schon geht es in die Hose.
Um solche unliebsamen Überraschungen zu vermeiden gibt es ![]()
Delphi-Quellcode:
procedure DoSomething( ACanvas : TCanvas );
var LPenRecall : TPenRecall; begin LPenRecall := TPenRecall.Create( ACanvas.Pen ); try ACanvas.Pen. // nach Belieben Pen verändern finally LPenRecall.Free; // Danach ist ACanvas.Pen wieder wie vorher end; end; |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Zitat:
|
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Zitat:
![]() ![]() |
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Na ja, ich lese auch nicht alles hier.
|
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
|
AW: Zeichnen auf Canvas und ZOrder bzw. Übermalen
Danke für eure Mithilfe.
gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:02 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz