2

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.

3
  • 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} }
    – user31034
    Apr 26, 2021 at 23:02
  • I don't understand the purpose of this comment. Could you explain to me, please?
    – Rashiq
    Apr 27, 2021 at 1:02
  • Replace last draw command by \draw[arrow](n2.east) to[jump] (n3.west);. When you say '\draw (n1)--(n2), you are making reference to n1.center` and n2.center although TiKZ only draws between borders. In this case jump uses a to syntax which draws between anchors without considering node's bodies.
    – Ignasi
    Apr 27, 2021 at 9:28

1 Answer 1

1

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

3
  • 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, 2021 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. Apr 27, 2021 at 21:51

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.