Bessere Anpassung der Linie an den Knoten in TiKZ

Bessere Anpassung der Linie an den Knoten in TiKZ

Ich verwende die Automatenbibliothek von TiKZ und füge Linien mit einer Dicke von 18pt zwischen den Knoten ein. Das Problem ist, dass die Grenze zwischen den Linien und dem Status nicht gut passt:

Bildbeschreibung hier eingeben

Das hätte ich gerne

Bildbeschreibung hier eingeben

Irgendwelche Ideen?

Hier ist ein Minimalbeispiel zur Erzeugung des ersten:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{automata}

\begin{document}

\begin{tikzpicture}[thick]
  \node[state] (1) {};
  \draw[-, blue!20, line width=18pt] (1) to (0,1);
\end{tikzpicture}

\end{document}

Antwort1

Hier ist ein Versuch mit Pfeilspitzen.
(Ich habe auch eine Lösung mit Verzierungen, aber die verwirren mich mehr als Pfeilspitzen.)

Leider Round Capfügt die Pfeilspitze nur reversedeinen Halbkreis vom Linienende hinzu (oder entfernt ihn mit der Option). Dies würde hervorragend funktionieren, wenn die Linienbreite doppelt so groß wie der Radius eines kreisförmigen Knotens wäre.

Der setup codefür die Pfeilspitze Hug Capberechnetetwas Mathematikund speichert drei Werte:

  • Radius (dieser wird von der Pfeiltaste übernommen length),
  • H, dies ist der Einzug (die Höhe) und
  • ein Winkel (es ist schließlich ein Bogen, der gezeichnet wird).

Es besteht die Möglichkeit, die Definition der Pfeilspitze um Optionen wie reversed, open, left, usw. zu erweitern.

Der deroundStil berechnet den Radius aus kreisförmigen Knoten. (Obwohl diese Antwort vom circle connection barStil und der Dekoration aus der mindmapBibliothek inspiriert ist, verwendet sie einen anderen Ansatz, um den Radius aus bereits vorhandenen Knoten zu extrahieren.)

Natürlich müssen die Pfade orthogonal zum Kreisrand sein.

toDiese Lösung muss mit / edge-Operatoren verwendet werden (sie verwendet \tikztostartund \tikztotargetzur automatischen Berechnung der Radien. Verwenden Sie nichts anderes line capsals butt(die Standardeinstellung). Dies kann auch innerhalb der Definition der Pfeilspitze überprüft werden.

Dies bricht ab, wenn die Linienbreite größer als der Durchmesser ist und auch bei sehr großen Radien (aber warum wird dies dann überhaupt verwendet?).

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{automata,arrows.meta}
\pgfdeclarearrow{
  name=Hug Cap,
  parameters=\the\pgfarrowlength,
  setup code={
    % h = r - .5 sqrt(4 r^2 - s^2)
    \pgfmathsetlengthmacro\pgfarrowh{\pgfarrowlength-.5*sqrt(4*\pgfarrowlength*\pgfarrowlength-\pgflinewidth*\pgflinewidth}
    % a = asin(s / (2 r))
    \pgfmathsetmacro\pgfarrowangle{asin(\the\pgflinewidth/(2*\the\pgfarrowlength))}
    \pgfarrowssavethe\pgfarrowlength % radius
    \pgfarrowssave\pgfarrowh         % h
    \pgfarrowssave\pgfarrowangle     % a
    \pgfarrowsupperhullpoint{0pt}{.5\pgflinewidth}
    \pgfarrowsupperhullpoint{\pgfarrowh}{.5\pgflinewidth}
    \pgfarrowssetlineend{.1pt}       % eeh :\
  },
  drawing code={
    \pgfpathmoveto{\pgfqpoint{\pgfarrowh}{-.5\pgflinewidth}}
    \pgfpatharc{180+\pgfarrowangle}{180-\pgfarrowangle}{\pgfarrowlength}
    \pgfpathlineto{\pgfqpoint{0pt}{.5\pgflinewidth}}
    \pgfpathlineto{\pgfqpoint{0pt}{-.5\pgflinewidth}}
    \pgfpathclose
    \pgfusepathqfill}}
\makeatletter
\def\qrr@tikz@circle{circle}
\newcommand*\qrr@getRadius[1]{%
  \def\qrr@radius{0pt}%
  \tikz@scan@one@point\pgfutil@firstofone(#1)\relax
  \iftikz@shapeborder
    \edef\qrr@shape{\csname pgf@sh@ns@\tikz@pp@name{\tikz@shapeborder@name}\endcsname}%
    \ifx\qrr@tikz@circle\qrr@shape
      % ah circle, get the radius!
      \begingroup
        \csname pgf@sh@np@\tikz@pp@name{\tikz@shapeborder@name}\endcsname
        \let\qrr@radius\radius
        \pgfmath@smuggleone\qrr@radius
      \endgroup
    \fi
  \fi}
\tikzset{
  deround/.style={
    /utils/exec={%
     \qrr@getRadius\tikztostart
     \ifdim\qrr@radius=0pt
       \def\qrr@arrowsettings{-}\else
       \edef\qrr@arrowsettings{{Hug Cap[length=+\qrr@radius]}-}\fi
     \qrr@getRadius\tikztotarget
     \ifdim\qrr@radius=0pt\else
       \edef\qrr@arrowsettings{\qrr@arrowsettings{Hug Cap[length=+\qrr@radius]}}\fi
   },
   arrows/.expanded=\qrr@arrowsettings}
}
\makeatother
\begin{document}
\begin{tikzpicture}[thick]
  \node[state]          (1) {};
  \node[state] at (2,1) (2) {abcdef};
  \path[line width=12pt, every edge/.append style=deround]
    (2) edge (1)
        edge[line width=10pt, red, out=150, in=90] (1);
  \path[line width=12pt] (1) edge[out=180-30, in=180+30, looseness=4, deround] (1);
\end{tikzpicture}
\end{document}

Ausgabe

Bildbeschreibung hier eingeben

Antwort2

Ich habe eine Möglichkeit gefunden, aber es scheint nicht die kanonische zu sein, sondern nur eine Möglichkeit, die funktioniert: Verwenden Sie Ebenen und erhöhen Sie dann die Länge der Zeile:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{automata}

\begin{document}

\pgfdeclarelayer{bg}
\pgfsetlayers{bg,main}
\begin{tikzpicture}[thick]
  \node[state,fill=white] (1) {};
  \begin{pgfonlayer}{bg}
    \draw[-,shorten >=-4pt,shorten <=-4pt,blue!20, line width=18pt]
    (1) to (0,1);
  \end{pgfonlayer}
\end{tikzpicture}

\end{document}

Ergebnis

BEARBEITEN Zweite Lösung, basierend auf dem Kommentar unten (verwenden Sie den Mittelpunkt als Koordinate anstelle längerer Linien)

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{automata}

\begin{document}

\pgfdeclarelayer{bg}
\pgfsetlayers{bg,main}
\begin{tikzpicture}[thick]
  \node[state,fill=white] (1) {};
  \begin{pgfonlayer}{bg}
    \draw[-,blue!20, line width=18pt]
    (1.center) to (0,1);
  \end{pgfonlayer}
\end{tikzpicture}

\end{document}

verwandte Informationen