4

I am using tikz to draw a graph. Basically I have a source (node (s)) and a sink (node (t)) that I want to connect with multiple parallel paths, which have multiple links in series.

I find that this solution places my nodes nicely, connects them correctly, but not smoothly,

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{arrows,decorations.pathmorphing,backgrounds,positioning,fit,petri,shapes.geometric,patterns,calc}

\begin{document}

\begin{tikzpicture}[vertex/.style={circle, draw}]

\node[vertex, minimum size=1cm] (s) at (0,0) {};
\node[vertex, minimum size=1cm] (t) at (12,0) {};

\foreach \r in {0,...,3} {
    \foreach \x in {1,...,4} {
        \path (s) to[out=20*\r, in=180-20*\r] node[vertex, pos=\x/5] (\r\x) {} (t); }}
% the nodes I am trying to link

\foreach \r in {0,...,3} {
    \draw[->] (s) -- (\r1);
    \draw[->] (\r4) -- (t);
    \foreach \x [count=\xi] in {2,...,4} {
        \draw[->] (\r\xi) -- (\r\x); }}
%the linkage is good, but does not curve nicely

\end{document}
\end{tikzpicture}

I would like the links to curve in the same manner that the path from (s) to (t) which traverse the nodes, with an arrow pointing at each node. I plotted in red the bending I would like to achieve with the linkage.Desired curves vs achieved curves so far

8

Instead of placing nodes along the path, I used the decorations.markings library to place on this path (length 1) at positions 0.2; 0.4; 0.6 and 0.8 two arrows > and Circle.

mark=between positions 0.2 and 1 step 0.2
with { 
        \draw[arrows = -{>Circle[open,length=8pt,width=8pt,fill=white]}] (0pt,0pt) -- (.1pt,0pt);
        }

The last arrows are placed by tracing the main paths that are traced with a single foreach loop.

\foreach \r [remember =\r as \lastr initially 0]in {0,...,3} {
        \path[draw,postaction={decorate},->] (s) to[out=20*\r, in=180-20*\r,->] 
        (t); 
        } 

Thus it is no longer necessary to have a double foreach loop.

screenshot

\documentclass[border=5mm,tikz]{standalone}

%\usepackage{tikz}
\usetikzlibrary{arrows,decorations.pathmorphing,backgrounds,positioning,fit,petri,shapes.geometric,patterns,calc}
\usetikzlibrary{decorations.markings,arrows.meta}

\begin{document}

\begin{tikzpicture}[vertex/.style={circle, draw},decoration={markings,
mark=between positions 0.2 and 1 step 0.2
with { 
        \draw[arrows = -{>Circle[open,length=8pt,width=8pt,fill=white]}] (0pt,0pt) -- (.1pt,0pt);
        }
       } 
]

\node[vertex, minimum size=1cm] (s) at (0,0) {};
\node[vertex, minimum size=1cm] (t) at (12,0) {};

\foreach \r [remember =\r as \lastr initially 0]in {0,...,3} {
        \path[draw,postaction={decorate},->] (s) to[out=20*\r, in=180-20*\r,->] 
        (t); 
        }       

\end{tikzpicture}
\end{document}
  • 2
    Thank you, that does solve it, in an unexpected way! – Olivier Massicot Jul 10 at 21:53
  • Voting down deserves an explanation. Without explanation this has no meaning other than gratuitous hostility. – AndréC Aug 4 at 4:57
2

This is based on this code. It allows one to draw the connections without shifting the nodes while bending the arrows.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,bending,decorations.markings} 
\tikzset{% inspired by https://tex.stackexchange.com/a/316050/121799
    arc arrow/.style args={%
    to pos #1 with length #2 and offset #3}{
    decoration={
        markings,
         mark=at position 0 with {\pgfextra{%
         \pgfmathsetmacro{\tmpArrowTime}{#2/(\pgfdecoratedpathlength)}
         \pgfmathsetmacro{\tmpArrowOffset}{#3/(\pgfdecoratedpathlength)}
         \xdef\tmpArrowTime{\tmpArrowTime}
         \xdef\tmpArrowOffset{\tmpArrowOffset}}},
        mark=at position {#1-\tmpArrowTime-\tmpArrowOffset} with {\coordinate(@1);},
        mark=at position {#1-2*\tmpArrowTime/3-\tmpArrowOffset} with {\coordinate(@2);},
        mark=at position {#1-\tmpArrowTime/3-\tmpArrowOffset} with {\coordinate(@3);},
        mark=at position {#1-\tmpArrowOffset} with {\coordinate(@4);
        \draw[-{Stealth[length=#2,bend]}]       
        (@1) .. controls (@2) and (@3) .. (@4);},
        },
     postaction=decorate,
     }
}


\begin{document}
\begin{tikzpicture}[vertex/.style={circle, draw},
insert vertices/.style={postaction={decorate,decoration={markings,
mark={between positions 0.2 and 0.8 step 0.2
with { 
        \node[vertex,fill=white](#1\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}){};
        }
       }}}},my arrow/.style={arc arrow=to pos #1 with length 2mm and offset 4pt} 
]

\node[vertex, minimum size=1cm] (s) at (0,0) {};
\node[vertex, minimum size=1cm] (t) at (12,0) {};

\foreach \r [remember =\r as \lastr initially 0]in {0,...,3} {
 \path[draw,insert vertices=\r,-{Stealth[bend,length=2mm]},
 my arrow/.list={1/5,2/5,3/5,4/5}] (s) to[out=20*\r, in=180-20*\r,->] 
        (t); 
}       
\end{tikzpicture}
\end{document}

enter image description here

On the other the solution by AndréC (which is in red), moves the circles away from the postions 0.2,0.4,....

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows.meta,bending,decorations.markings} 
\tikzset{% inspired by https://tex.stackexchange.com/a/316050/121799
    arc arrow/.style args={%
    to pos #1 with length #2 and offset #3}{
    decoration={
        markings,
         mark=at position 0 with {\pgfextra{%
         \pgfmathsetmacro{\tmpArrowTime}{#2/(\pgfdecoratedpathlength)}
         \pgfmathsetmacro{\tmpArrowOffset}{#3/(\pgfdecoratedpathlength)}
         \xdef\tmpArrowTime{\tmpArrowTime}
         \xdef\tmpArrowOffset{\tmpArrowOffset}}},
        mark=at position {#1-\tmpArrowTime-\tmpArrowOffset} with {\coordinate(@1);},
        mark=at position {#1-2*\tmpArrowTime/3-\tmpArrowOffset} with {\coordinate(@2);},
        mark=at position {#1-\tmpArrowTime/3-\tmpArrowOffset} with {\coordinate(@3);},
        mark=at position {#1-\tmpArrowOffset} with {\coordinate(@4);
        \draw[-{Stealth[length=#2,bend]}]       
        (@1) .. controls (@2) and (@3) .. (@4);},
        },
     postaction=decorate,
     }
}


\begin{document}
\begin{tikzpicture}[vertex/.style={circle, draw},
insert vertices/.style={postaction={decorate,decoration={markings,
mark={between positions 0.2 and 0.8 step 0.2
with { 
        \node[vertex,fill=white](#1\pgfkeysvalueof{/pgf/decoration/mark info/sequence number}){};
        }
       }}}},my arrow/.style={arc arrow=to pos #1 with length 2mm and offset 4pt} 
]

\node[vertex, minimum size=1cm] (s) at (0,0) {};
\node[vertex, minimum size=1cm] (t) at (12,0) {};

\foreach \r [remember =\r as \lastr initially 0]in {0,...,3} {
 \path[draw,insert vertices=\r,-{Stealth[bend,length=2mm]},
 my arrow/.list={1/5,2/5,3/5,4/5}] (s) to[out=20*\r, in=180-20*\r,->] 
        (t); 
}       
\begin{scope}[red,opacity=0.8,vertex/.style={circle, draw},decoration={markings,
mark=between positions 0.2 and 1 step 0.2
with { 
        \draw[arrows = -{>Circle[open,length=8pt,width=8pt,fill=white]}] (0pt,0pt) -- (.1pt,0pt);
        }
       } 
]

\node[vertex, minimum size=1cm] (s) at (0,0) {};
\node[vertex, minimum size=1cm] (t) at (12,0) {};

\foreach \r [remember =\r as \lastr initially 0]in {0,...,3} {
        \path[draw,postaction={decorate},->] (s) to[out=20*\r, in=180-20*\r,->] 
        (t); 
        }       
\end{scope}
\end{tikzpicture}
\end{document}

enter image description here

OLDER ANSWER: The syntax you may be looking may be

to[bend left=<angle>]

\documentclass{article}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture}[vertex/.style={circle, draw}]

\node[vertex, minimum size=1cm] (s) at (0,0) {};
\node[vertex, minimum size=1cm] (t) at (12,0) {};

\foreach \r in {0,...,3} {
    \foreach \x in {1,...,4} {
        \path (s) to[out=20*\r, in=180-20*\r] node[vertex, pos=\x/5] (\r\x) {} (t); }}
% the nodes I am trying to link

\foreach \r in {0,...,3} {
    \draw[-stealth] (s) to[bend left={\r*30/pow(\r+1,2)}]  (\r1);
    \draw[-stealth] (\r4) to[bend left={\r*30/pow(\r+1,2)}]  (t);
    \foreach \x [count=\xi] in {2,...,4} {
        \draw[-stealth] (\r\xi) to[bend left={\r*20/pow(\r+1,3/2)}] (\r\x); }}
%the linkage is good, but does not curve nicely
\end{tikzpicture}

\end{document}

enter image description here

  • 1
    Thank you, surprisingly this method almost works! I wouldn't have betted on fixing the bending angle. However, it's slightly off, so I'd go with the solution of AndréC. – Olivier Massicot Jul 10 at 21:55
  • @OlivierMassicot OK, I added a version with decorations.markings in which the circles are nodes whose style is controlled by your vertex style, and not displaced. (In AndréC's code the centers of the circles are not at positions 1/5,2/5,..., but the right end of those is there.) Also this code places named nodes, which you can use later (which is what you thought to want). – user121799 Jul 10 at 22:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.