Canvas: Linien mit Pfeilspitzen?

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
Antworten
Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 168
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Canvas: Linien mit Pfeilspitzen?

Beitrag von Jorg3000 »

Moin!
Ich möchte schräge Linien mit schräggestellten Pfeilspitzen auf ein Canvas zeichnen.
Zufällig habe ich für HTML5/Javascript ein schön kurzes Beispiel gefunden: https://riptutorial.com/html5-canvas/ex ... arrowheads
Der auf der Seite gezeigte, schräge Pfeil ist genau das, was mir vorschwebt.

Bezüglich Lazarus fehlt mir dazu gerade die Idee, wie ich die Winkel und gedrehten Koordinaten berechne.
Es ist schon verdammt lange her, dass ich mal mit Sinus/Cosinus gearbeitet habe.

Oder gibt es dafür Funktionen? Wer kann mir Starthilfe geben?
Danke und Grüße, Jörg

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Canvas: Linien mit Pfeilspitzen?

Beitrag von Winni »

Hi!

Sinus und Cosinus sind zwei Räuber in irgendeinem Asterix-Album .....

Sinus und Cosinus erklär ich Dir nicht - das haben schon andere getan. Z.B. Regiomontanus so um 1450 ....

Hier hast Du Deinen Pfeil.
Ein Image wird benötigt und die unit math muss eingebunden sein.

Code: Alles auswählen

procedure TForm1.Button2Click(Sender: TObject);
const  Deg2Rad =  180/pi;
       winkel = 30;
       WinkelPfeil = 15;
       Laenge= 100;
       LaengePfeil = 20;
 var P0,P1,P2,P3 : TPoint;
     sinus,cosinus : single;
begin
  Image1.Canvas.Brush.Color := clWhite;
  Image1.Canvas.FillRect(0,0,Image1.width,Image1.Height);
  P0 := Point(200,100);
  math.SinCos(winkel*deg2Rad,sinus,cosinus);
  P1 := point (Round(cosinus*laenge)+P0.x,round(sinus*laenge)+P0.y);
  Image1.Canvas.Line(P0,P1);
 
  math.SinCos((Winkel+WinkelPfeil-180)*deg2Rad,sinus,cosinus);
  P2 := Point(Round(cosinus*LaengePfeil)+P1.x,Round(sinus*LaengePfeil)+P1.y);
  Image1.Canvas.Line(P2,P1);
 
  math.SinCos((Winkel-WinkelPfeil+180)*deg2Rad,sinus,cosinus);
  P3 := Point(Round(cosinus*LaengePfeil)+P1.x,Round(sinus*LaengePfeil)+P1.y);
  Image1.Canvas.Line(P3,P1);
end;
Falls Dir das alles zu kompliziert ist:
Bei der BGRAbitmap fallen die Pfeilenden aus der Tüte.


Winni

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 168
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: Canvas: Linien mit Pfeilspitzen?

Beitrag von Jorg3000 »

Wow, sogar schon als fertige Lösung!
Meinen allerbesten Dank! :)

Sinus/Cosinus wollte ich auch nicht erklärt bekommen - mit meiner Frage wollte ich darauf hinaus, ob es für FP-Grafik ähnliche Koordinatentransformations-Funktionen wie in Javascript gibt (in dem o.g. JS-Beispiel findet ja keine manuelle Sinus-Rechnerei statt).

Nochmals Danke für die Lösung!
Grüße, Jörg

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Canvas: Linien mit Pfeilspitzen?

Beitrag von Winni »

Hi!

Wie ich schon gesagt habe: mit BGRAbitmap geht das viel einfacher.

Als Beispiel einen Standard-Pfeil an beiden Enden unsd einen "Indianer"-Pfeil.

Bild anbei.

Code: Alles auswählen

uses ......BGRABitmap, BGRABitmapTypes;

procedure TForm1.Button3Click(Sender: TObject);
var bmp : TBGRAbitmap;
    P0,P1,P2,P3  : TPointF;
    R : TRect;
begin
     Image1.width := 400;
     Image1.Height := 200;
     Image1.Picture.Bitmap.SetSize(Image1.width, Image1.Height);
     bmp := TBGRABitmap.create(Image1.width,Image1.height,CSSNavajoWhite);

    // Standard
     bmp.ArrowStartAsTriangle(3,false,true,1.0);
     bmp.ArrowEndAsTriangle(3,false,true,1.0);
     p0 := PointF(50,100);
     P1 := PointF(350,150);
     bmp.DrawLineAntialias(P0.x,P0.y,P1.x,P1.y,CSSRed,2);

     // Indianer
     bmp.ArrowStartAsClassic(false,true,2);
     bmp.ArrowEndAsClassic(true,false,1);
     bmp.ArrowEndOffset := -6.0;
     bmp.ArrowEndRepeat := 3;
     P2 := PointF (250,55);
     P3 := PointF (350,70);
     bmp.DrawLineAntialias(P2.x,P2.y,P3.x,P3.y,CSSBrown,2);

 R := Rect(0,0,Image1.width,Image1.Height);
 Image1.Canvas.CopyRect(R,bmp.canvas,R);
 bmp.Free;
end;


Winni
Dateianhänge
BGRAarrows.png
BGRAarrows.png (4.3 KiB) 2029 mal betrachtet

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Canvas: Linien mit Pfeilspitzen?

Beitrag von Winni »

Hi!

Falls jemand einen richtigen Pfeil benötigt - ich musste gerade mal ein paar Fingerübungen machen ...
Benutzt BGRAbitmap

Code: Alles auswählen


procedure TForm1.Button4Click(Sender: TObject);
const Radius1 = 120;
      Radius2 = 200;
      Deg2Rad =  pi/180;
      offset = 30;
var bmp : TBGRAbitmap;
    Center: TPointF;
    ar : ArrayOfTPointF;
    R : TRect;
    delta, sinus,  cosinus : single;
    angle,k: Integer;

begin
     Image1.width := 400;
     Image1.Height := 400;
     Image1.Picture.Bitmap.SetSize(Image1.width, Image1.Height);
     bmp := TBGRABitmap.create(Image1.width,Image1.height,CSSNavajoWhite);
     center := PointF(bmp.width / 2-offset,bmp.height/2);
     setLength(ar,2*181+3);
     k := 0;
     For angle := 180 to 360 do
       begin
       math.sincos(angle*deg2Rad,sinus,cosinus);
       ar[k] := PointF (cosinus*radius1+center.x, sinus*radius1+center.y);
       inc(k);
							end;
     ar[k] := PointF(ar[k-1].x-offset,ar[k-1].y);
     inc(k);
     delta := (Radius2 - radius1) / 2;
     ar[k] := PointF (center.x+radius1+delta,ar[k-1].y+offset);
     inc(k);
     ar[k] := PointF(center.x+Radius2+offset,center.y);
     inc (k);
     for angle := 360 downto 180 do
       begin
       delta := (angle - 180)/180 * (Radius2-radius1);
       math.SinCos(angle*Deg2Rad,sinus,cosinus);
       ar[k] := PointF (cosinus*(radius1+delta)+Center.x,
                        sinus*(radius1+delta)+center.y);
       inc(k);
							end;
     bmp.DrawPolygonAntialias(ar,cssBlack,2,cssRed);
     r := rect (0,0,bmp.width,bmp.height);
     Image1.Canvas.CopyRect(R,bmp.canvas,R);
     bmp.free;
end;
Grüße
Winni
Dateianhänge
BGRArrow2.png
BGRArrow2.png (13.68 KiB) 1957 mal betrachtet

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Canvas: Linien mit Pfeilspitzen?

Beitrag von fliegermichl »

Cool!

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Canvas: Linien mit Pfeilspitzen?

Beitrag von Winni »

Hi!

Weil bei BGRA die Arrows so einfach aus der Tüte fallen, hab ich mal einen ArrowGenerator gebaut, der alle Möglichkeiten in einer Gui zusammenfast.

Die zahlreichen Parameter sind selbserklärend.

Project und Screenshot anbei.

Viel Spaß beim Rumspielen!

Winni
Dateianhänge
ArrowGenerator.zip
(37.06 KiB) 116-mal heruntergeladen
ArrowGenerator.png
ArrowGenerator.png (73.93 KiB) 1871 mal betrachtet

Antworten