Conecte vértices de um polígono regular por setas curvas

Conecte vértices de um polígono regular por setas curvas

Tenho um diagrama que é simplesmente um conjunto de nós distribuídos uniformemente em torno de um círculo. Como posso conectar os nós com setas circulares?

por exemplo, suponha que temos um pentágono com nós em cada vértice. Obviamente, todos os vértices do pentágono formam um círculo. Quero conectar os nós por setas "paralelas" ao círculo. (então no geral parece um ciclo)

Responder1

Aqui está uma possibilidade: usar duas vezes nós do tipo regular polygon, um interno e outro externo, ambos colocados em círculos.

\documentclass[a4paper,12pt]{article}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}

\newcommand{\polygonsides}{5}

\begin{document}
\begin{minipage}[t][0.3\textheight]{0.45\textwidth}
Clockwise [option \texttt{bend left}]:
\begin{flushleft}
\begin{tikzpicture}
% Internal cirlce with polygon
\draw[blue](0,0)circle(1.5cm);
\node[regular polygon, regular polygon sides=\polygonsides, minimum size=3cm, draw, name=x] at (0,0) {};
% Nodes on vertices
\foreach \corner in {1,2,...,\polygonsides}
\node[circle,ball color=blue] at (x.corner \corner){};

% External polygon
\node[regular polygon, regular polygon sides=\polygonsides, minimum size=4cm, draw=none, name=p] at (0,0) {};
% Invisible nodes on vertices
\foreach \corner in {1,2,...,\polygonsides}
\node at (p.corner \corner){};

% Connections
\foreach \source/\destination in {p.corner 1/p.corner 5,p.corner 5/p.corner 4,p.corner 4/p.corner 3,p.corner 3/p.corner 2,p.corner 2/p.corner 1}
\draw[-stealth,shorten <=0.2cm,shorten >=0.2cm,thick,blue](\source)to[bend left](\destination);
\end{tikzpicture}
\end{flushleft}
\end{minipage} 
\begin{minipage}[t][0.3\textheight]{0.55\textwidth}
Counterclockwise [option \texttt{bend right}]:
\begin{flushleft}
\begin{tikzpicture}
% Internal cirlce with polygon
\draw[red](0,0)circle(1.5cm);
\node[regular polygon, regular polygon sides=\polygonsides, minimum size=3cm, draw, name=x] at (0,0) {};
% Nodes on vertices
\foreach \corner in {1,2,...,\polygonsides}
\node[circle,ball color=red] at (x.corner \corner){};

% External polygon

\node[regular polygon, regular polygon sides=\polygonsides, minimum size=4cm, draw=none, name=p] at (0,0) {};

% Nodes on vertices
\foreach \corner in {1,2,...,\polygonsides}
\node at (p.corner \corner){};

% Connections
\foreach \source/\destination in {p.corner 1/p.corner 2,p.corner 2/p.corner 3,p.corner 3/p.corner 4,p.corner 4/p.corner 5,p.corner 5/p.corner 1}
\draw[-stealth,shorten <=0.2cm,shorten >=0.2cm,thick,red](\source)to[bend right](\destination);
\end{tikzpicture}
\end{flushleft}
\end{minipage} 
\end{document}

Resultado:

insira a descrição da imagem aqui

O polígono externo não é desenhado porque é usado apenas como referência para definir corretamente os vértices que são o ponto inicial e final das setas. Claro, é possível deixar as setas mais próximas do polígono declarando um raio mais próximo para este polígono externo: agora a distância é 1cm. A seguir há dois exemplos: no primeiro as setas estão no sentido horário enquanto no segundo estão no sentido anti-horário. Para conseguir essas duas coisas são necessárias:

  • usando opções bend leftde sentido horário e bend rightanti-horário;
  • conecte o par source/destinationno sentido horário ou anti-horário, tendo em mente que os nós e os vértices são numerados no sentido anti-horário:

insira a descrição da imagem aqui

Responder2

Uma versão compacta (não automatizou o cálculo da circunferência, pois não tenho certeza se é isso que é solicitado)

\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric,decorations.markings}

\begin{document}
\begin{tikzpicture}[decoration={
    markings,
    mark=between positions 0 and 1 step 2.51376 cm with {\arrow{latex}}
    }
]
\draw[postaction={decorate}] (90:2cm) arc (-270:90:2cm);
\node[draw,red,regular polygon, regular polygon sides=5,minimum height=4cm] {};
\end{tikzpicture}
\end{document}

insira a descrição da imagem aqui

Responder3

A seguir, utilizo a biblioteca shapes.geometricque define uma forma chamada regular polygonpara que você tenha uma solução geral independente de quantos lados o polígono tenha. Também preciso de uma macro auxiliar \pgfmathsetlenghtbetweenanchorsque calcule o comprimento entre duas âncoras do mesmo nó.

Para desenhar o arco, uso a sintaxe fornecidaaquie preciso do ângulo entre dois cantos conforme mencionadoaqui.

insira a descrição da imagem aqui

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{shapes.geometric}

\begin{document}

\makeatletter
\def\pgfmathsetlenghtbetweenanchors#1#2#3#4{%
  % #1: length
  % #2: node
  % #3: first anchor
  % #4: second anchor
  \pgfpointdiff{%
    \pgfpointanchor{#2}{#3}}{%
    \pgfpointanchor{#2}{#4}}%
  \pgfmathparse{veclen(\pgf@x,\pgf@y)}%
  #1=\pgfmathresult pt}
\makeatother

\newlength\nagonradius

\begin{tikzpicture}
  \def\nsides{5}%
  \node[regular polygon,
        regular polygon sides = \nsides,
        draw,
        rotate=25,
        minimum size = 3cm] (\nsides-agon) {};

  \pgfmathsetlenghtbetweenanchors\nagonradius{\nsides-agon}{center}{%
    corner 2}% 
  \foreach \n [remember = \n as \m (initially \nsides)] in
    {1,...,\nsides} {%
      \pgfmathanglebetweenpoints{%
        \pgfpointanchor{\nsides-agon}{center}}{%
        \pgfpointanchor{\nsides-agon}{corner \m}}%
      \let\anglem\pgfmathresult
      \pgfmathanglebetweenpoints{%
        \pgfpointanchor{\nsides-agon}{center}}{%
        \pgfpointanchor{\nsides-agon}{corner \n}}%
      \let\anglen\pgfmathresult
      \ifdim\anglen pt < \anglem pt
        \pgfmathparse{\anglen + 360}%
        \let\anglen\pgfmathresult
      \fi
      \draw[->,red] ([shift={(\anglem:\nagonradius)}]\nsides-agon.center) arc
        (\anglem:\anglen:\nagonradius);} 

\end{tikzpicture}

\begin{tikzpicture}
  \def\nsides{7}%
  \node[regular polygon,
        regular polygon sides = \nsides,
        draw,
        rotate=25,
        minimum size = 3cm] (\nsides-agon) {};

  \pgfmathsetlenghtbetweenanchors\nagonradius{\nsides-agon}{center}{%
    corner 2}% 
  \foreach \n [remember = \n as \m (initially \nsides)] in
    {1,...,\nsides} {%
      \pgfmathanglebetweenpoints{%
        \pgfpointanchor{\nsides-agon}{center}}{%
        \pgfpointanchor{\nsides-agon}{corner \m}}%
      \let\anglem\pgfmathresult
      \pgfmathanglebetweenpoints{%
        \pgfpointanchor{\nsides-agon}{center}}{%
        \pgfpointanchor{\nsides-agon}{corner \n}}%
      \let\anglen\pgfmathresult
      \ifdim\anglen pt < \anglem pt
        \pgfmathparse{\anglen + 360}%
        \let\anglen\pgfmathresult
      \fi
      \draw[->,red] ([shift={(\anglem:\nagonradius)}]\nsides-agon.center) arc
        (\anglem:\anglen:\nagonradius);} 

\end{tikzpicture}


\end{document}

Responder4

Aqui está uma solução usando arc:

insira a descrição da imagem aqui

E o código:

\documentclass{standalone}
\usepackage{tikz}
\pgfmathsetmacro{\radius}{2}
\begin{document}
\foreach \nbn in {3,5,7,9}{
  \begin{tikzpicture}
    \pgfmathsetmacro{\angle}{360/\nbn}
    % center
    \node {\nbn{} nodes};
    % draw nodes
    \foreach \i in {1,...,\nbn}{
      \node at (\angle*\i:\radius) {$N_\i$};
    }
    % draw arrows (clockwise)
    \foreach \i in {1,...,\nbn}{
      \draw[-latex,very thick,red!50!black]
      ({\angle*(\i+.2)}:\radius-.2)
      arc (\angle*(\i+.2):\angle*(\i+1-.2):\radius-.2);
    }

    % draw arrows (anticlockwise)
    \foreach \i in {1,...,\nbn}{
      \draw[-latex,very thick,green!50!black]
      ({\angle*(\i-.2)}:\radius+.2)
      arc (\angle*(\i-.2):\angle*(\i-1+.2):\radius+.2);
    }
  \end{tikzpicture}
}
\end{document}

informação relacionada