AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Canvas - gleichschenkliches gefülltes Dreieck
Thema durchsuchen
Ansicht
Themen-Optionen

Canvas - gleichschenkliches gefülltes Dreieck

Ein Thema von stahli · begonnen am 30. Mai 2015 · letzter Beitrag vom 1. Jun 2015
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#1

Canvas - gleichschenkliches gefülltes Dreieck

  Alt 30. Mai 2015, 20:03
Ich zeichne auf einen Canvas ein Dreieck.


Delphi-Quellcode:
procedure TTest.PaintBackground(aGui: TsoGui; aBitmap: TBitmap;
  aRect: TRect);
const
  Size = 5;
var
  A: TPoint;
  B: TPoint;
  C: TPoint;
  X, Y, S: Integer;
begin
  ...

  aBitmap.Canvas.Brush.Color := clGray;
  aBitmap.Canvas.Pen.Color := clBlack;

  X := aRect.Left + (aRect.Width div 2);
  Y := aRect.Top + (aRect.Height div 2);
  S := (Size div 2);
  
  ...
  
  A := Point(X - S, Y - S);
  B := Point(X + S, Y - S);
  C := Point(X, Y + S);

  ...

  aBitmap.Canvas.Polygon([A, B, C]);
end;
Das Dreieck ist aber nicht symmetrisch.
Zuerst lege ich einen Mittelpunkt fest und dann die Entfernung um den Mittelpunkt.
Es wird von LinksOben nach RechtsOben, dann nach UntenMitte gezogen und dann zurück nach LinksOben.

Nach meinem Verständnis sollte das Dreieck damit symmetrisch aussehen, was es aber nicht ist.

Muss man das irgendwie anders lösen?
Miniaturansicht angehängter Grafiken
dreieck.png  
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli (30. Mai 2015 um 20:06 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Helmi
Helmi

Registriert seit: 29. Dez 2003
Ort: Erding, Republik Bayern
3.336 Beiträge
 
Delphi XE2 Professional
 
#2

AW: Canvas - gleichschenkliches gefülltes Dreieck

  Alt 30. Mai 2015, 20:30
kann es sein, dass du Rundungsfehler hast?

bei
Delphi-Quellcode:
const
   Size = 5;
   X, Y, S: Integer;
begin
   ...
   S := (Size div 2);
   ...
end;
würde normalerweis 2,5 rauskommen, was aber nicht in einen Integer passt.

Vielleicht hilft es, wenn du die Berechnungen mit Floats machst und dann auf Integer rundest für die Canvas-Befehle
mfg
Helmi

>> Theorie ist Wissen, dass nicht funktioniert - Praxis ist, wenn alles funktioniert und keiner weiss warum! <<
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Canvas - gleichschenkliches gefülltes Dreieck

  Alt 30. Mai 2015, 20:36
"Div" rundet direkt ab. Es kommt also 2 raus.
Vom Mittelpunkt aus gesehen hat das Dreieck jeweils einen Abstand von 2 Pixel.
Das sollte also so passen.

Das Problem liegt wohl bei der unterschiedlichen Rundung der Windows-API bei den einzelnen Linien.
Ich schätze mal dass man damit leben muss oder sonst die Linien einzeln berechnen muss.

Aber vielleicht weiß ja jemand noch etwas...
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Helmi
Helmi

Registriert seit: 29. Dez 2003
Ort: Erding, Republik Bayern
3.336 Beiträge
 
Delphi XE2 Professional
 
#4

AW: Canvas - gleichschenkliches gefülltes Dreieck

  Alt 30. Mai 2015, 21:00
mmh - ich hab das grad nachgestellt
es scheint wirklich ein Zeichnenproblem zu sein.
von C nach B scheint es um ein Pixel zu weit links zu sein
mfg
Helmi

>> Theorie ist Wissen, dass nicht funktioniert - Praxis ist, wenn alles funktioniert und keiner weiss warum! <<
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#5

AW: Canvas - gleichschenkliches gefülltes Dreieck

  Alt 30. Mai 2015, 21:06
  • Ein Kreis mit dem Durchmesser eines Pixels ist ein Punkt. Geht nicht anders auf einem digitalen System.
  • Ein Kreis mit einem Durchmesser von zwei Pixeln ist ein Quadrat. Geht nicht anders auf einem digitalen System.
  • Ein Kreis mit dem Durchmesser von 100 Pixeln mag zwar für das menschliche Auge wie ein Kreis aussehen, ist aber in Wirklichkeit ein Vieleck. Ein gleichschenkliges Dreieck ist ein Kreis mit lediglich drei Knotenpunten. Nimmst du 5 Punkte, hast du ein Fünfeck. Nimmst du 30 Punkte, kannst du die Ecken des 30-Ecks kaum noch erkennen. Nimmst du 100 oder mehr Punkte, ist das für dich ein Kreis, technisch gesehen aber noch immer ein 100-Eck.

Du kannst eine diagonale Linie nicht mit gleichviel Pixeln abbilden wie ein horizontale oder eine vertikale Linie. Machst du dein Dreieck größer, wird dieser Eindruck verwischt. Bei vier Pixeln Grundfläche gibt es keinen echten Mittelpunkt mehr für die Spitze des Dreiecks.
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Canvas - gleichschenkliches gefülltes Dreieck

  Alt 30. Mai 2015, 21:12
Ja das ist schon richtig.
Man könnte aber die rechte Linie genau so runden wie die linke (also spiegeln).

Natürlich weiß die Polygon-Funktion nicht, dass man das als Betrachter als sinnvoll erachten würde.

Vielleicht wird eine Linie links+unten nach rechts+oben auch generell anders auf- und abgerundet als in der anderen Richtung.


Also ich kann akzeptieren wenn man sagt, "die Standard-Polygon-Funktion kann diesen Sonderfall nicht explizit behandeln", auch wenn das zu einem besseren Ergebnis führen würde.
So wird es wohl liegen...
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#7

AW: Canvas - gleichschenkliches gefülltes Dreieck

  Alt 30. Mai 2015, 21:18
Du kannst ja mal mit dieser Procedure rumspielen.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#8

AW: Canvas - gleichschenkliches gefülltes Dreieck

  Alt 30. Mai 2015, 22:26
Bei LineTo fehlt ja auch das letzte Pixel, aber ich hätte gedacht, daß somit nur beim letzen Punkt einer PolyLine das selbe Problem auftritt und es sich bei einem Polygon aufhebt, da dort der letzte Punkt eh dort ist, wo sich schon der erste Punkt hingemalt hatte.
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#9

AW: Canvas - gleichschenkliches gefülltes Dreieck

  Alt 30. Mai 2015, 22:44
Hallo, dein Dreieck ist vollkommen korrekt, auch wenn es nicht so aussieht.
Wenn man sich nur mal die Endpunkte noch mit einzeichnet, dann fällt es bestimmt besser auf, daß es wirklich stimmt.

Delphi-Quellcode:
procedure TForm5.FormPaint(Sender: TObject);
var
  X, Y, S, I, J, K: Integer;
  A: array[0..2] of TPoint;
begin
  X := 20;
  Y := 20;
  S := 3;

  A[0] := Point(X - S, Y - S);
  A[1] := Point(X + S, Y - S);
  A[2] := Point(X, Y + S {+ 1});

  for I := Low(A) to High(A) do
    for J := -1 to +1 do
      for K := -1 to +1 do
        Canvas.Pixels[A[I].X + J, A[I].Y + K] := clRed;

  Canvas.Pen.Color := clBlue;
  Canvas.Polygon(A);
end;
Die Zeichenfunktion der rechten Linie ist natürlich andersrum. (von oben nach unten ... von unten nach oben)
Links von oben aus jeweils Zwei runter und dann Eines nach rechts.
Und Rechts jeweils Zwei nach oben und Eines nach rechts.

Passt also ganz genau dazu, wie du es auch zeichnen wolltest.
Bei einer geraden Anzahl (siehe Auskommentiertes) passt es wohl besser zusammen, für diesen Fall der 2:1-Steigung = 2x.
Miniaturansicht angehängter Grafiken
unbenannt.png   unbenannt1.png  
$2B or not $2B

Geändert von himitsu (30. Mai 2015 um 23:00 Uhr)
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#10

AW: Canvas - gleichschenkliches gefülltes Dreieck

  Alt 31. Mai 2015, 00:18
@stahli

Zu dem Problem. Das liegt in dem Verständnis was eine Canvas-Linie ist. Um die zu verstehen muss man ein Schritt zurück treten. Denkt man nicht darüber nach was eine Canvas-Linie eigentlich ist, denkt man vorschnell, dass es eine mit einem 1-Pixel gezeichnete Linie ist, von Punkt A nach Punkt B. Ist sie aber nicht.

Im Grunde ist es eine mit einem Pinsel der Stärke x-Pixel gezeichnete Linie. Und Pinsel der Breite x ist immer in der Form berechnet. Intern mit Nachkommastellen. Guck was Perlsau oben über den Kreis geschrieben hat. Jeder Pixel ist im Grunde ein berechneter Kreis. Der kleinste Kreis ist ein Pixel breit. Er sieht quadratisch aus, ist aber ein berechneter Kreis. D. h. am Anfang und Ende eine Linie, selbst wenn sie ein Pixel breit ist, ist ein Halbkreis. Ist der Pinsel 1-Pixel breit, sieht der Halbkreis wie ein Quadrat aus, ist aber ein Halbkreis.

Und nun muss man einen Schritt zurück treten und sich angucken was das alles ist. So rechteckig das für uns auch aussieht, es ist alles mit Nachkommastellen berechnet. Du hast von Punkt A nach Punkt B 5-Pixel weit gezeichnet. Intern kann die Position B aber ein Wert mit Dezimalstellen sein.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:42 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