4

I have a diagram where the arrow lines between \nodes overlap and I would like them to have a semicircle (or some sort of indication really) on their intersection point to communicate which arrow is going where. I have been consulting this answer for my task. The 'flexible' solution is working as intended and, as aptly named, works with -|, |- variants of the connection which I have a need for.

However, the arrow lines seem to originate from the center of my nodes a and b like so. I would have hoped from them to look like that of the arrow between x and y just with the hump added. enter image description here

My attempt.

\documentclass[10pt, border=1in]{standalone}

\usepackage{tikz} \usetikzlibrary{shapes.geometric, arrows, arrows.meta} \usetikzlibrary{positioning} \usetikzlibrary{calc}

\tikzstyle{object} = [draw, rectangle, minimum width=2cm, minimum height=1cm, text centered, draw=black] \tikzstyle{arrow} = [thick,->,>=Triangle]

\pgfmathsetmacro{\jumpswap}{1} \tikzset{ % set up keys for radius, position, swap jump radius/.estore in=\jumpradius, jump pos/.estore in=\jumppos, jump swap/.code={\pgfmathsetmacro{\jumpswap}{\jumpswap-1}}, jump radius=0.15cm, jump pos=0.5, % set up styles for the various to-paths -u-/.style={ % straight line to path={ let \p1=(\tikztostart),\p2=(\tikztotarget),\n1={atan2(\y2-\y1,\x2-\x1)} in (\p1) -- ($($(\p1)!\jumppos!(\p2)$)!\jumpradius!(\p1)$) arc[start angle=\n1+180,delta angle=-180\jumpswap,radius=\jumpradius] -- (\p2)} }, -u|/.style={ % -| path with jump on horizontal leg to path={ let \p1=(\tikztostart),\p2=(\tikztostart-|\tikztotarget), \n1={atan2(\y2-\y1,\x2-\x1)} in (\p1) -- ($($(\p1)!\jumppos!(\p2)$)!\jumpradius!(\p1)$) arc[start angle=\n1+180,delta angle=-180\jumpswap,radius=\jumpradius] --(\p2) -- (\tikztotarget)} }, |u-/.style={ % |- path with jump on vertical leg to path={ let \p1=(\tikztostart),\p2=(\tikztostart|-\tikztotarget), \n1={atan2(\y2-\y1,\x2-\x1)} in (\p1) -- ($($(\p1)!\jumppos!(\p2)$)!\jumpradius!(\p1)$) arc[start angle=\n1+180,delta angle=-180\jumpswap,radius=\jumpradius] -- (\p2) -- (\tikztotarget)} }, -|u/.style={ % -| path with jump on vertical leg to path={ let \p1=(\tikztostart-|\tikztotarget),\p2=(\tikztotarget), \n1={atan2(\y2-\y1,\x2-\x1)} in (\tikztostart) -- (\p1) -- ($($(\p1)!\jumppos!(\p2)$)!\jumpradius!(\p1)$) arc[start angle=\n1+180,delta angle=-180\jumpswap,radius=\jumpradius] -- (\p2)} }, |-u/.style={ % |- path with jump on horizontal leg to path={ let \p1=(\tikztostart|-\tikztotarget),\p2=(\tikztotarget), \n1={atan2(\y2-\y1,\x2-\x1)} in (\tikztostart) -- (\p1) -- ($($(\p1)!\jumppos!(\p2)$)!\jumpradius!(\p1)$) arc[start angle=\n1+180,delta angle=-180\jumpswap,radius=\jumpradius] -- (\p2)} }, % define the jump style, set it to use straight line by default jump/.style={-u-,#1}, jump/.default={} }

\begin{document}

\begin{tikzpicture}[node distance=2cm]
    \node(n1)[object]{x};
    \node(n2)[object, below of=n1, xshift=-3.5cm]{a};
    \node(n3)[object, right of=n2, xshift=5cm]{b};
    \node(n4)[object, below of=n1, yshift=-2cm]{y};

    \draw[arrow](n1)--(n4);
    \draw[arrow](n2) to[jump] (n3); % connecting arrow called here
\end{tikzpicture}

\end{document}

I am open to any other solution that enables displaying the desired intersection marker(s). Thank you for reading.

Rashiq
  • 337
  • Only code you need in preamble is `\tikzstyle{object} = [draw, rectangle, minimum width=2cm, minimum height=1cm, text centered, draw=black] \tikzstyle{arrow} = [thick,->,>=Triangle]

    \tikzset{ jump/.style={ to path={ let \p1=(\tikztostart),\p2=(\tikztotarget),\n1={atan2(\y2-\y1,\x2-\x1)} in (\tikztostart) -- ($($(\tikztostart)!#1!(\tikztotarget)$)!0.15cm!(\tikztostart)$) arc[start angle=\n1+180,end angle=\n1,radius=0.15cm] -- (\tikztotarget)} }, jump/.default={0.5} }`

    –  Apr 26 '21 at 23:02
  • I don't understand the purpose of this comment. Could you explain to me, please? – Rashiq Apr 27 '21 at 01:02
  • Replace last draw command by \draw[arrow](n2.east) to[jump] (n3.west);. When you say '\draw (n1)--(n2), you are making reference ton1.centerandn2.centeralthoughTiKZonly draws between borders. In this casejumpuses ato` syntax which draws between anchors without considering node's bodies. – Ignasi Apr 27 '21 at 09:28

1 Answers1

3

Here's an alternative method of achieving the jumping arc which uses my spath3 library. It locates the intersection of the paths and automatically places an arc at the intersection point in the over path. It additionally breaks the under path at the arc.

\documentclass[10pt, border=1in]{standalone}
%\url{https://tex.stackexchange.com/q/594585/86}

\usepackage{tikz} \usetikzlibrary{ shapes.geometric, arrows.meta, positioning, calc, intersections, spath3 }

\tikzset{ object/.style={ draw, rectangle, minimum width=2cm, minimum height=1cm, text centered, draw=black }, arrow/.style={ thick, ->, >=Triangle }, bridging path/.initial=arc, bridging span/.initial=8pt, bridging gap/.initial=4pt, bridge/.style 2 args={ spath/split at intersections with={#1}{#2}, spath/insert gaps after components={#1}{\pgfkeysvalueof{/tikz/bridging span}}, spath/join components upright with={#1}{\pgfkeysvalueof{/tikz/bridging path}}, spath/split at intersections with={#2}{#1}, spath/insert gaps after components={#2}{\pgfkeysvalueof{/tikz/bridging gap}}, } }

\AtBeginDocument{ \tikz[overlay] \path[spath/save=arc] (0,0) arc[radius=1cm, start angle=180, delta angle=-180]; }

\begin{document}

\begin{tikzpicture}[node distance=2cm]
    \node(n1)[object]{x};
    \node(n2)[object, below of=n1, xshift=-3.5cm]{a};
    \node(n3)[object, right of=n2, xshift=5cm]{b};
    \node(n4)[object, below of=n1, yshift=-2cm]{y};

\path[spath/save=up] (n1) -- (n4); \path[spath/save=along] (n2) -- (n3);

\tikzset{bridge={along}{up}}

\draw[arrow,spath/use=up]; \draw[arrow,spath/use=along];

\end{tikzpicture}

\end{document}

Diagram with arcs automatically placed at intersection points

Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751
  • Thank you. Could provide some guidance on how I would use this if the arrow between the nodes is bent using the ++(x,y) and is passing over multiple bent arrows between other nodes? – Rashiq Apr 27 '21 at 21:46
  • @Rashiq The line \tikzset{bridge={along}{up}} adds the jumps to the along path and the breaks to the up path, so you simply repeat that line for each pair of paths where you want to have one path passing over another. There are some more complicated examples on this site, I'll dig one out for you to see. – Andrew Stacey Apr 27 '21 at 21:51
  • https://tex.stackexchange.com/a/583847/86 – Andrew Stacey Apr 27 '21 at 21:52