# Symmetrical touching arrows with variable node sizes and positions

I search a solution for symmetrical touching arrows in the mid point with variable node sizes because of changing content. Schrödinger's cat helped me already to get this code:

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\begin{scope}
\node(A){A};
\node[below = of A](B){B};
\node[left = of A](C){C};
\node[right = of A](D){D};
\node[left = of B](E){E};
\node[right = of B](F){F};
\path (barycentric cs:A=1,B=1,D=1,F=1) coordinate (ABDF)
(barycentric cs:A=1,B=1,C=1,E=1) coordinate (ABCE);
\draw[->] (B.east) to[out=45,in=-90] (ABDF) to[out=90,in=-45] (A.east);
\draw[->] (F.west) to[out=135,in=-90] (ABDF) to[out=90,in=-135] (D.west);
\draw[->] (A.west) to[out=-135,in=90] (ABCE) to[out=-90,in=135] (B.west);
\draw[->] (C.east) to[out=-45,in=90] (ABCE) to[out=-90,in=45]  (E.east);
\end{scope}
\end{tikzpicture}
\end{document}


This example looks good as long as you don't replace the letters by different content. However, I will have different content and with that different node sizes and coordinates of the nodes.

Replacing the letters A, B, C, D, E and F by words, the symmetry gets lost. See this example:

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\begin{scope}
\node(A){A};
\node[below = of A](B){Hello};
\node[left = of A](C){Tree};
\node[left = of B](E){Car};
\node[right = of B](F){Children's doll};
\path (barycentric cs:A=1,B=1,D=1,F=1) coordinate (ABDF)
(barycentric cs:A=1,B=1,C=1,E=1) coordinate (ABCE);
\draw[->] (B.east) to[out=45,in=-90] (ABDF) to[out=90,in=-45] (A.east);
\draw[->] (F.west) to[out=135,in=-90] (ABDF) to[out=90,in=-135] (D.west);
\draw[->] (A.west) to[out=-135,in=90] (ABCE) to[out=-90,in=135] (B.west);
\draw[->] (C.east) to[out=-45,in=90] (ABCE) to[out=-90,in=45]  (E.east);
\end{scope}
\end{tikzpicture}
\end{document}


How can I control easily the symmetry of the arrows for different content?

Here is something that may go in the right direction. It is not absolutely symmetrical since already the layout of the nodes is not. Now the barycenter is computed on the basis of the start and end anchors, not the node centers. Also a tilt is introduced to account for the fact that the horizontal position barycenter of the upper nodes (or, more precisely, their start anchors) does not coincide with the corresponding horizontal position of the lower nodes.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{calc,positioning}
\begin{document}
\begin{tikzpicture}[get slope/.style n args={4}{insert path={
let \p1=($($(#1)!0.5!(#2)$)-($(#3)!0.5!(#4)$)$),\n1={atan2(\y1,\x1)} in
}}]
% usage: #1=top left, #2=top right, #3=bottom left, #4=bottom right
\begin{scope}
\node(A){A};
\node[below = of A](B){Hello};
\node[left = of A](C){Tree};
\node[left = of B](E){Car};
\node[right = of B](F){Children's doll};
\path (A.east) coordinate (A0) (F.west) coordinate (F0)
(B.east) coordinate (B0)  (D.west) coordinate (D0)
(barycentric cs:A0=1,F0=1,B0=1,D0=1) coordinate (ABDF)
(A.west) coordinate (A1)  (B.west) coordinate (B1)
(C.east) coordinate (C1)  (E.east) coordinate (E1)
(barycentric cs:A1=1,B1=1,C1=1,E1=1) coordinate (ABCE);
\draw[->,get slope={A0}{D0}{B0}{F0}]
(B0) to[out=45,in=\n1-180] (ABDF) to[out=\n1,in=-45] (A0);
\draw[->,get slope={A0}{D0}{B0}{F0}]
(F0) to[->,out=135,in=\n1-180] (ABDF) to[out=\n1,in=-135] (D0);
\draw[->,get slope={C1}{A1}{E1}{B1}]
(A1) to[out=-135,in=\n1] (ABCE) to[out=\n1-180,in=135] (B1);
\draw[->,,get slope={C1}{A1}{E1}{B1}]
(C1) to[out=-45,in=\n1] (ABCE) to[out=\n1-180,in=45]  (E1);
\end{scope}
\end{tikzpicture}
\end{document} While I think this looks reasonable here, this recipe may not necessarily yield reasonable results for arbitrary node configurations, in which, say, three nodes cluster around one point and the fourth one is far away.

• Thank you very much. So far, this looks like a good solution.
– Auk
May 12, 2020 at 20:33