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 '18, 19:59

cis's gravatar image

cis
9.5k95459491
Akzeptiert-Rate: 29%

bearbeitet 05 Jul '18, 14: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 '18, 15:22

Community's gravatar image

Community
21
Akzeptiert-Rate: 56%

bearbeitet 08 Jul '18, 16:25

cis's gravatar image

cis
9.5k95459491

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 '18, 16: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 '18, 16:58) Community

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

(05 Jul '18, 23:11) cis

@cis Ich habe einfach meine Antwort editiert.

(06 Jul '18, 07:33) Community
2

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

(06 Jul '18, 07:49) saputello
2

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

(06 Jul '18, 07:57) Community
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 '18, 16: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 '18, 16:39) Community
Ergebnis 5 von 8 show 3 more comments
Deine Antwort
Vorschau umschalten

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

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ügen Sie einfach zwei Leerzeichen an die Stelle an der die neue Linie sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Frage-Themen:

×731
×6

gestellte Frage: 04 Jul '18, 19:59

Frage wurde gesehen: 7,493 Mal

zuletzt geändert: 08 Jul '18, 16:39