Verwandt mit: https://texwelt.de/wissen/fragen/22338/tikz-feinschliff-einer-pfeilspitze


Ich möchte ein Kommando erstellen, dass es erlaubt einen single arrow aus der shapes-Bibliothek zwischen zwei Koordinaten, etwa A und B, zu zeichnen.

Dazu habe ich Winkel und Abstand der Koordinaten berechnet.

Der Winkel ist schonmal der richtige, die Länge des Pfeils scheint nahezu die Richtige zu sein. Aber mit der Position des Pfeils stimmt etwas nicht.

alt text

Öffne in Overleaf
\documentclass[margin=5mm]{standalone}

\usepackage{amsmath, amssymb}

\usepackage{tikz}
 \usetikzlibrary{shapes}

\begin{document}

\tikzset{Pfeil/.style={
single arrow, draw, 
minimum width=5ex, 
%minimum height=13ex, 
inner sep=1ex,
%text height=1ex,
%text depth=0ex,
single arrow head extend=1ex
}}

\begin{tikzpicture}

\coordinate (A) at (0,0);
\coordinate (B) at (2,2);
% ...

\path (A);
\pgfgetlastxy{\Ax}{\Ay} 
\path (B);
\pgfgetlastxy{\Bx}{\By}

%\pgfmathsetmacro{\Length}{veclen(\Ax,\By)}
\pgfmathsetmacro{\Length}{sqrt((\By-\Ay)^2+(\Bx-\Ax)^2)}
\pgfmathsetmacro{\Angle}{atan((\By-\Ay)/(\Bx-\Ax))}

\path[] (A)  node[
Pfeil, 
rotate=\Angle, 
xshift=1*0.5*\Bx, 
yshift=0*0.5*\By, 
minimum height=1.0*\Length, 
%minimum width=1.0*\Bx, 
]  {};

% Kontrolle
\draw[red] (A) -- (B) ;
\node[red] at (0,5) {\Ax, \Ay, \Bx, \By, \Angle, \Length};
\end{tikzpicture}

\end{document}

gefragt 04 Jul, 13:59

cis's gravatar image

cis
7.3k13155247
Akzeptiert: 72%

bearbeitet 05 Jul, 08:16


Verwandt mit meiner Antwort auf die verlinkte Frage und teilweise basierend auf https://tex.stackexchange.com/a/432147/121799. Wenn Du calc lädst, kannst Du Dir all die \pgfgetlastxy und \pgfmathsetmacro sparen, und alles in einen Style für einen edge path stecken. Du brauchst dann nur noch \draw (A) edge[Pfeil] (B); zu sagen.

Öffne in Overleaf
\documentclass[margin=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.arrows,calc}
\tikzset{Pfeil/.style=%
{to path={let \p1 = ($(\tikztotarget)-(\tikztostart)$),
            \n1 = {int(mod(scalar(atan2(\y1,\x1))+360, 360))}, % calculate angle in range [0,360)
            \n2 = {veclen(\x1,\y1)}
        in \pgfextra{\typeout{\n1,\n2,\x1,\y1}}
         (\tikztotarget)
        node[draw,single arrow,
             minimum height=\n2-\pgflinewidth,
%            minimum width=5ex, 
             %minimum height=13ex, 
             inner sep=1ex,
             %text height=1ex,
             %text depth=0ex,
             single arrow head extend=1ex,
             rotate=\n1, % not shape border rotate, because that for some reason didn't work
             anchor=tip, % anchor=tip added, pos=0.5 removed
             ]{}
         }}}

\begin{document}
\begin{tikzpicture}
\coordinate (A) at (0,0);
\coordinate (B) at (2,2);
\draw (A) edge[Pfeil] (B);
\draw[red] (A) -- (B);
\end{tikzpicture}
\end{document}

alt text


Ergänzung:

Mit kleineren Anpassungen kann Pfeil=double als optionales Argument verwendet werden; gegenüber Pfeil bzw. gleichbedeutend Pfeil=single (default).

Z.B. \draw[] (A) edge[Pfeil=double] (B);

alt text

Öffne in Overleaf
\documentclass[margin=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.arrows,calc}
\tikzset{
Pfeil/.style args={#1}{
to path={let \p1 = ($(\tikztotarget)-(\tikztostart)$),
\n1 = {int(mod(scalar(atan2(\y1,\x1))+360, 360))}, % calculate angle in range [0,360)
\n2 = {veclen(\x1,\y1)} in \pgfextra{\typeout{\n1,\n2,\x1,\y1}} (\tikztotarget)
node[
#1 arrow, % single arrow,
#1 arrow head extend=1ex,
draw,
minimum height=\n2-\pgflinewidth,
% minimum width=5ex, 
% minimum height=13ex, 
inner sep=1ex,
%text height=1ex,
%text depth=0ex,
rotate=\n1,% 
anchor=east,% ehgemals: tip bei single / tip 1 bei double arrow
]{}
}},
Pfeil/.default=single
}

\begin{document}
\begin{tikzpicture}
\coordinate (A) at (0,-1);
\coordinate (B) at (2,2);
\draw (A) edge[Pfeil] (B);
    \draw[red] (A) -- (B);
\draw[] ([xshift=2cm]A) edge[Pfeil=double] ([xshift=2cm]B);
\end{tikzpicture}
\end{document}
Permanenter link

beantwortet 05 Jul, 09:22

Murmeltier's gravatar image

Murmeltier
1.2k64

bearbeitet 08 Jul, 10:25

cis's gravatar image

cis
7.3k13155247

Aja, sehr gut. Kann ich -nur spaßeshalber- irgendwie die Werte anzeigen lassen? \node[] at (0,5) {\n1, \n2, \p1}; oder \node[] at (0,5) {\pgfmathparse{\n1}\pgfmathresult}; scheint nicht zu gehen.

(05 Jul, 10:52) cis

@cis Du kannst beispielsweise let ... in \pgfextra{\typeout{\n1,\n2,\x1,\x2,\y1,\y2}} geben um Dir \n1, \n2 und die x- und y-Koordinaten der Punkte ausgeben zu lassen.

(05 Jul, 10:58) Murmeltier

@Murmeltier Hab ich jetzt spontan nicht hinbekommen - vll. mache ich eine neue Frage daraus. ;)

(05 Jul, 17:11) cis

@cis Ich habe einfach meine Antwort editiert.

(06 Jul, 01:33) Murmeltier
2

@cis Damit es zu keinen Missverständnissen kommt: \typeout schreibt die Informationen in die log-Datei.

(06 Jul, 01:49) saputello
2

@saputello Und zumindest bei mir auch auf die Konsole... ;-) Danke für den Kommentar!

(06 Jul, 01:57) Murmeltier
1

@Murmeltier Ich habe bei deiner AW eine kleine Ergänzung vorgenommen. Falls Dir das missfällt, kannst Du sie wieder löschen.

(08 Jul, 10:26) cis

@cis Ja, vielen Dank, sieht super aus! (Im Prinzip kann man auch zwei Argumente einbauen, das zweite dann für zusätzliche Optionen, aber das ist vielleicht übertrieben... ;-)

(08 Jul, 10:39) Murmeltier
Ergebnis 5 von 8 Alle anzeigen
Deine Antwort auf die Frage (nicht auf andere Antworten)
Knebel-Vorschau

Folge dieser Frage

Per E-Mail:

Wenn Du Dich anmeldest, kannst Du Updates hier abonnieren

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs füge einfach zwei Leerzeichen an die Stelle ein, an der die neue Zeile sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Zugeordnete Themen:

×598
×3

Frage gestellt: 04 Jul, 13:59

Frage wurde angeschaut: 108 Mal

Zuletzt aktualisiert: 08 Jul, 10:39