Автоматическое рисование путей между узлами разной формы на дуге

Автоматическое рисование путей между узлами разной формы на дуге

У меня есть изображение, на котором я хотел бы нарисовать стрелки между узлами, где стрелки все находятся "на одной окружности". Я могу добиться того, чего хочу, вручную следующим образом:

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{shapes}
\begin{document}
\begin{tikzpicture}[ultra thick, -stealth]
  \node[circle,fill] (a) at (0: 1) {};
  \node[rectangle,minimum width=1cm,fill](b) at (120: 1) {};
  \node[rectangle,minimum height=1cm,fill](c) at (240: 1) {};
  \draw[dashed] (85: 1) arc (85: 30: 1) ;
  \draw (330:1) arc (330: 280:1) ;
  \draw[dashed] (200:1) arc (200: 140:1);
\end{tikzpicture}
\end{document}

Но если мои узлы имеют разные формы и размеры, мне нужно найти координаты, которые работают вручную. Что мне действительно хотелось бы сделать, так это найти, где края узла пересекают окружность, и нарисовать дуги, используя эти края. Есть ли автоматический способ сделать это?Этот ответэто частичное решение, но, похоже, мне все равно придется выбирать дуги и shortenдлины вручную...

Фактический вариант использования заключается в том, что узлы будут содержать изображения с разными соотношениями сторон. Я аппроксимировал проблему, используя некоторые узлы неуклюжей формы.

решение1

Хайко Обердиек рулит!!!! --

https://tex.stackexchange.com/a/250270/197451

введите описание изображения здесь

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{bending}

\begin{document}
    \begin{tikzpicture}[
    ->,   
    thick,
    main node/.style={circle, fill=blue!20, draw},
    ]
    \newcommand*{\MainNum}{5}
    \newcommand*{\MainRadius}{1.5cm} 
    \newcommand*{\MainStartAngle}{90}
    
    % Print main nodes, node names: p1, p2, ...
    \path
    (0, 0) coordinate (M)
    \foreach \t [count=\i] in {A, Hello\\World, 3, foobar, $\cdot$} {
        +({\i-1)*360/\MainNum + \MainStartAngle}:\MainRadius)
        node[main node, align=center] (p\i) {\t}
    }
    ;  
    
    % Calculate the angle between the equal sides of the triangle
    % with side length \MainRadius, \MainRadius and radius of circle node
    % Result is stored in \p1-angle, \p2-angle, ...
    \foreach \i in {1, ..., \MainNum} {
        \pgfextracty{\dimen0 }{\pgfpointanchor{p\i}{north}} 
        \pgfextracty{\dimen2 }{\pgfpointanchor{p\i}{center}}
        \dimen0=\dimexpr\dimen2 - \dimen0\relax 
        \ifdim\dimen0<0pt \dimen0 = -\dimen0 \fi
        \pgfmathparse{2*asin(\the\dimen0/\MainRadius/2)}
        \global\expandafter\let\csname p\i-angle\endcsname\pgfmathresult
    }
    
    % Draw the arrow arcs
    \foreach \i [evaluate=\i as \nexti using {int(mod(\i, \MainNum)+1}]
    in {1, ..., \MainNum} {  
        \pgfmathsetmacro\StartAngle{   
            (\i-1)*360/\MainNum + \MainStartAngle
            + \csname p\i-angle\endcsname
        }
        \pgfmathsetmacro\EndAngle{
            (\nexti-1)*360/\MainNum + \MainStartAngle
            - \csname p\nexti-angle\endcsname
        }
        \ifdim\EndAngle pt < \StartAngle pt
        \pgfmathsetmacro\EndAngle{\EndAngle + 360}
        \fi
        \draw
        (M) ++(\StartAngle:\MainRadius)
        arc[start angle=\StartAngle, end angle=\EndAngle, radius=\MainRadius]
        ;
    }
    \end{tikzpicture}
\end{document}

Связанный контент