| Autor |
Beitrag |
AXMD
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Fr 04.03.05 17:51
Moin  !
Ich baue grade meinen Complex Calculator aus und mit fällt auf, dass ich ein Zeigerdiagramm mit Strichen habe; ich möchte allerdings ein Zeigerdiagramm mit Zeigern, daher hätt ich gerne Pfeilspitzen... hab mich schon etwas mit den Winkelfunktionen gespielt, aber das brachte nichts.
Hier der Code, wo der "Pfeil" (ohne Spitze) gezeichnet wird. (w div 2, h div 2) ist der Koordinatenursprung.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| for i := Low(vars) to High(vars) do begin Pen.Color := vars[i].Color; MoveTo(w div 2, h div 2); LineTo(Round(w div 2 + vars[i].Real * scalex), Round(h div 2 - vars[i].Img * scaley)); Font.Color := Pen.Color; if vars[i].Real > 0 then TextOut(Round(w div 2 + vars[i].Real * scalex) - TextWidth(vars[i].Name) - 10, Round(h div 2 - vars[i].Img * scaley) - TextHeight(vars[i].Name) div 2 , vars[i].Name) else TextOut(Round(w div 2 + vars[i].Real * scalex) + 10, Round(h div 2 - vars[i].Img * scaley) - TextHeight(vars[i].Name) div 2 , vars[i].Name) end; |
Jemand eine Idee für die Pfeilspizen?
AXMD
|
|
sourcehunter
      
Beiträge: 482
Win XP | Suse 10.1
Delphi 2005 Pers.
|
Verfasst: Fr 04.03.05 18:18
Probiers mal mit nem Polygon. So, dass du von der Spitze z.B. 10 "Pixel" zurückgehst und dann 5 zu jeder Seite senkrecht zur Linie.
_________________ Linux und OpenSource rulez!
|
|
AXMD 
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Fr 04.03.05 18:21
| sourcehunter hat folgendes geschrieben: | | Probiers mal mit nem Polygon. So, dass du von der Spitze z.B. 10 "Pixel" zurückgehst und dann 5 zu jeder Seite senkrecht zur Linie. |
Das "senkrecht" ist ja mein eigentliches Problem. Woher weiß ich, wie ich zeichnen muss damit es genau senkrecht wird...
AXMD
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Fr 04.03.05 18:28
Sagen wir einfachheitshalber, dass deine Linie im Koordinatenursprung beginnt.
D.h. Linie von 0,0 bis X,Y
Die Linie senkrecht dazu ist dann 0,0 bis -Y,X. Wieso?
Das Skalarprodukt der beiden Vektoren (X,Y)*(-Y,X)=0 (und das ist die Definition von "senkrecht")
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Fr 04.03.05 18:37
Also ich leite das kurz her, damit die Anwendung klar ist.
Länge der Linie L := sqrt(X^2+Y^2);
Die untere Pfeilkante sei W Pixels und die Höhe H Pixels.
Der Schnittpunkt untere Pfeilkante mit Linie ist dann bei
PX := X-X/L*H;
PY := Y-Y/L*H;
Von dort aus möchtest du senkrecht dazu eine Linie zeichnen. Wie oben erwäht lautet die Einheitssenkrechte:
SX := -Y/L;
SY := X/L;
Die linke, untere Pfeilecke ist dann bei:
Punkt A: PX+SX*W/2 ; PY+SY*W/2
Die rechte, untere Pfeilecke bei:
Punkt B: PX-SX*W/2 ; PY-SY*W/2
Das zu zeichende Dreieck besteht also aus den 3 Punkten: Die Spitze, A und B
Ich probiers schnell aus und korrigiere das noch, wenn nötig.
//Edit: Scheint zu funktionieren  Verschieben kannst du den Pfeil dann selbst
//Edit2: Hab noch ne kleine Modifikation gemacht, sodass die untere Kante nicht einfach gerade ist (sieht doof aus)
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:
| procedure TForm1.Button1Click(Sender: TObject); const H = 30; C = 25; W = 20; Var L, PX, PY, SX, SY, X, Y, X1,Y1,X2,Y2 : Extended; begin X := 100; Y := 20; L := sqrt(X*X+Y*Y); PX := X-X/L*H; PY := Y-Y/L*H; SX := -Y/L; SY := X/L; with Canvas do begin X1 := PX+SX*W/2; Y1 := PY+SY*W/2; X2 := PX-SX*W/2; Y2 := PY-SY*W/2; MoveTo(0,0); LineTo(Trunc(X), Trunc(Y)); Polygon([Point(Trunc(X), Trunc(Y)), Point(round(X1), round(Y1)), Point(Trunc(X-X/L*C), Trunc(Y-Y/L*C)), Point(round(X2), round(Y2))]); end; end; |
Gruss,
Simon
Zuletzt bearbeitet von delfiphan am Fr 04.03.05 18:53, insgesamt 1-mal bearbeitet
|
|
AXMD 
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Fr 04.03.05 18:51
Danke dir vielmals, ich werd's mal ausprobieren...
AXMD
|
|
AXMD 
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Fr 04.03.05 19:05
Nein, es funktioniert nicht ganz. Der Code funzt bei mir (angepasst) seltsamerweise nur im vierten Quadranten richtig...
AXMD
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Fr 04.03.05 19:06
Komisch. Hast du die Funktion richtig erweitert? Hier die backfertige Version:
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 DrawArrow(Canvas : TCanvas; PX1,PY1,PX2,PY2 : Integer); const H = 30; C = H * 6 div 7; W = H * 2 div 3; Var L, PX, PY, X, Y : Extended; begin X := PX2-PX1; Y := PY2-PY1; L := sqrt(X*X+Y*Y); PX := X*(1-H/L); PY := Y*(1-H/L); with Canvas do begin MoveTo(PX1,PY1); LineTo(PX2,PY2); Polygon([Point(PX2, PY2), Point(Round(PX1+PX-Y/L*W/2), Round(PY1+PY+X/L*W/2)), Point(Trunc(PX1+X-X/L*C), Trunc(PY1+Y-Y/L*C)), Point(Round(PX1+PX+Y/L*W/2), round(PY1+PY-X/L*W/2))]); end; end;
procedure TForm1.Button1Click(Sender: TObject); begin DrawArrow(Canvas, 200,30,100,100); end; |
|
|
AXMD 
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Fr 04.03.05 19:17
Also ich glaub heut kapier ich's irgendwie nicht
Wenn ich deine Funktion so aufrufe DrawArrow(Canvas, 0, 0, x, y); wobei x und y die Endpunkte meines "Pfeils" (Strichs  ) sind funzts gar nicht (keine Pfeile, nirgendwo).
Oder hab ich da was falsch gemacht?
AXMD
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Fr 04.03.05 19:20
Funzt nichts? Du siehst nichts?
DrawArrow(Image1.Canvas, X1,Y1,X2,Y2) zeichnet einen Pfeil von (X1,Y1) bis (X2,Y2). Die Pfeilspitze ist bei (X2,Y2)
Ich habe die Funktion in allen Richtungen getestet... Bei mir geht's.
Zuletzt bearbeitet von delfiphan am Fr 04.03.05 19:22, insgesamt 1-mal bearbeitet
|
|
AXMD 
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Fr 04.03.05 19:22
Hier mal der ganze Code... dein Code zeichnet bei mir leider gar nichts.
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:
| procedure TForm1.PaintBox1Paint(Sender: TObject); var w, h: Integer; scalex, scaley: Double; tempvars: Array of Double; i: Integer; x, y: Integer; begin with PaintBox1.Canvas do begin w := PaintBox1.Width; h := PaintBox1.Height; Brush.Style := bsSolid; Brush.Color := clWhite; Pen.Color := clWhite; Rectangle(0, 0, w, h); Brush.Style := bsClear; Pen.Color := clBlack; MoveTo(w div 2, 0); LineTo(w div 2, h); MoveTo(0, h div 2); LineTo(w, h div 2); SetLength(tempvars, Length(vars) + 1); for i := Low(vars) to High(vars) do tempvars[i] := Abs(vars[i].Real); tempvars[Length(vars)] := Abs(loesung.Real); scalex := MaxValue(tempvars); SetLength(tempvars, 0); if scalex = 0 then scalex := 100; scalex := (w div 2 - 10) / scalex; SetLength(tempvars, Length(vars) + 1); for i := Low(vars) to High(vars) do tempvars[i] := Abs(vars[i].Img); tempvars[Length(vars)] := Abs(loesung.Img); scaley := MaxValue(tempvars); SetLength(tempvars, 0); if scaley = 0 then scaley := 100; scaley := (h div 2 - 10) / scaley; MoveTo(Round(w div 2 + scalex), h div 2 - 5); LineTo(Round(w div 2 + scalex), h div 2 + 5); TextOut(Round(w div 2 + scalex) - 2, h div 2 + 8, '1'); MoveTo(w div 2 + 5, Round(h div 2 - scaley)); LineTo(w div 2 - 5, Round(h div 2 - scaley)); TextOut(w div 2 - 14, Round(h div 2 - scaley) - 5, '1'); try for i := Low(vars) to High(vars) do begin Pen.Color := vars[i].Color; MoveTo(w div 2, h div 2); LineTo(Round(w div 2 + vars[i].Real * scalex), Round(h div 2 - vars[i].Img * scaley)); x := Round(w div 2 + vars[i].Real * scalex); y := Round(h div 2 - vars[i].Img * scaley); DrawArrow(Canvas, 0, 0, x, y); Font.Color := Pen.Color; if vars[i].Real > 0 then TextOut(Round(w div 2 + vars[i].Real * scalex) - TextWidth(vars[i].Name) - 10, Round(h div 2 - vars[i].Img * scaley) - TextHeight(vars[i].Name) div 2 , vars[i].Name) else TextOut(Round(w div 2 + vars[i].Real * scalex) + 10, Round(h div 2 - vars[i].Img * scaley) - TextHeight(vars[i].Name) div 2 , vars[i].Name) end; Pen.Color := loesung.Color; MoveTo(w div 2, h div 2); LineTo(Round(w div 2 + loesung.Real * scalex), Round(h div 2 - loesung.Img * scaley)); Font.Color := Pen.Color; if loesung.Real > 0 then TextOut(Round(w div 2 + loesung.Real * scalex) - TextWidth(loesung.Name) - 10, Round(h div 2 - loesung.Img * scaley) - TextHeight(loesung.Name) div 2 , loesung.Name) else TextOut(Round(w div 2 + loesung.Real * scalex) + 10, Round(h div 2 - loesung.Img * scaley) - TextHeight(loesung.Name) div 2 , loesung.Name) except TextOut(100, 100, 'Ungültige Eingabe'); end; end; end; |
AXMD
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Fr 04.03.05 19:24
Statt diese Zeilen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| MoveTo(w div 2, h div 2); LineTo(Round(w div 2 + vars[i].Real * scalex), Round(h div 2 - vars[i].Img * scaley)); x := Round(w div 2 + vars[i].Real * scalex); y := Round(h div 2 - vars[i].Img * scaley); DrawArrow(Canvas, 0, 0, x, y); |
Nur das hier:
Delphi-Quelltext 1:
| DrawArrow(PaintBox1.Canvas, w div 2, h div 2, Round(w div 2 + vars[i].Real * scalex), Round(h div 2 - vars[i].Img * scaley)); |
|
|
AXMD 
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Fr 04.03.05 19:29
Es ändert sich was.... jetzt ist gar kein Pfeil mehr da...
Delphi-Quelltext 1: 2: 3:
| x := Round(w div 2 + vars[i].Real * scalex); y := Round(h div 2 - vars[i].Img * scaley); DrawArrow(Canvas, w div 2, h div 2, x, y); |
Ergibt (Lösung wird separat gezeichnet!)
 AXMD
|
|
AXMD 
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Fr 04.03.05 19:32
Die PaintBox vergessen... *argx*
Danke dir vielmals, kommst in die Danksagungen im Readme und bei deiner Funktion kommt ein entsprechender Comment in den Code
Btw: könnt ich den Code vielleicht ohne dem Verbindungsstrich zwischen den beiden Enden haben
Also
/|\
|
|
statt
/|\
-|-
|
Thx
AXMD
Zuletzt bearbeitet von AXMD am Fr 04.03.05 19:34, insgesamt 1-mal bearbeitet
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Fr 04.03.05 19:32
Kopier einfach mal die obere Zeile.
Wichtig: Paintbox1.Canvas
sonst wird implizit Form1.Canvas angenommen!
//Edit: Okay, dann ist ja gut
Wegen der Funktion musste mich nicht gleich auflisten (kannst aber, wenn du willst  )
So ich muss jetzt raus.. Schönen Abend noch
*und weg
//Edit2: Und hiermit gebe ich dir die Erlaubnis mit dem Code zu tun was du willst
Delphi-Quelltext 1: 2: 3: 4:
| Polygon([Point(PX2, PY2), Point(Round(PX1+PX-Y/L*W/2), Round(PY1+PY+X/L*W/2)), Point(PX2, PY2), Point(Round(PX1+PX+Y/L*W/2), round(PY1+PY-X/L*W/2))]); |
*wirklich weg 
|
|
AXMD 
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Fr 04.03.05 19:50
Vielen lieben Dank nochmal.
| Readme hat folgendes geschrieben: | Ein herzliches Dankeschön geht an "delphifan" für die Hilfestellung beim Implementieren der Pfeilspitzen . |
Thx
AXMD
|
|
|