9

I have 4 circle nodes with different sizes.

Is there a simple way (TikZ, Asymptote,...) to connected them with circular arrow arcs?

enter image description here

\documentclass[border=5mm,tikz]{standalone}
\begin{document}
\begin{tikzpicture}[every node/.style={circle,draw,fill=white}]
\def\r{3}
\draw[red] (0,0) circle (\r);

% 4 nodes with different sizes
\path
(180:\r) node (Sp) {Spring}
(90:\r)  node (Su) {Summer}
(0:\r)   node (Au) {Autumn}
(-90:\r) node (Wi) {Winter};

% How to make arrow arcs cicular? (the red one with arrow tips)
\begin{scope}[-stealth,bend left]
\draw (Sp) to (Su);
\draw (Su) to (Au);
\draw (Au) to (Wi);
\draw (Wi) to (Sp);
\end{scope}
\end{tikzpicture}
\end{document}

7 Answers 7

3

Here is one way to do it in Asymptote with true arcs.

The intersect function returns an array of two times where the two paths intersect. The subpath function trims the arc to the intersection times.

I have not wrapped the code into a LaTeX document because I tend to process Asymptote with the asy command.

unitsize(1inch);

path Autumn = shift( 1, 0)*scale(0.35)*unitcircle;
path Winter = shift( 0,-1)*scale(0.30)*unitcircle;
path Spring = shift(-1, 0)*scale(0.32)*unitcircle;
path Summer = shift( 0, 1)*scale(0.36)*unitcircle;

draw(Autumn);
draw(Winter);
draw(Spring);
draw(Summer);

label("Autumn", ( 1, 0));
label("Winter", ( 0,-1));
label("Spring", (-1, 0));
label("Summer", ( 0, 1));

path p1 = arc((0,0), 1, 0, -90);
draw(subpath(p1, intersect(p1,Autumn)[0], intersect(p1,Winter)[0]), red, Arrow);

path p2 = arc((0,0), 1, 270, 180);
draw(subpath(p2, intersect(p2,Winter)[0], intersect(p2,Spring)[0]), red, Arrow);

path p3 = arc((0,0), 1, 180, 90);
draw(subpath(p3, intersect(p3,Spring)[0], intersect(p3,Summer)[0]), red, Arrow);

path p4 = arc((0,0), 1, 90, 0);
draw(subpath(p4, intersect(p4,Summer)[0], intersect(p4,Autumn)[0]), red, Arrow);

enter image description here

7

You can compute the intersections of the node boundaries and the circle to draw the arcs. For your convenience, I packed all the stuff in a pic. I kept the red circle in to prove that the arcs perfectly cover it.

\documentclass[border=5mm,tikz]{standalone}
\usetikzlibrary{arrows.meta,bending,calc,intersections}
\begin{document}
\begin{tikzpicture}[every node/.style={circle,draw,fill=white},
 pics/circular arc/.style args={from #1 to #2}{code={
 \path[name path=arc] 
  let \p1=(#1),\p2=(#2),\n1={atan2(\y1,\x1)},\n2={atan2(\y2,\x2)},
    \n3={ifthenelse(abs(\n1-\n2)<180,\n2,\n2-360)}
  in (\n1:\r) arc(\n1:\n3:\r);
 \draw[-{Stealth[bend]},pic actions,
    name intersections={of=#1 and arc,by=arcstart},
    name intersections={of=#2 and arc,by=arcend}] 
    let \p1=(arcstart),\p2=(arcend),\n1={atan2(\y1,\x1)},\n2={atan2(\y2,\x2)},
     \n3={ifthenelse(abs(\n1-\n2)<180,\n2,\n2-360)}
  in (\n1:\r) arc(\n1:\n3:\r);
 }}]
\def\r{3}
\draw[red] (0,0) circle (\r);

% 4 nodes with different sizes
\path
(180:\r) node[name path=Sp] (Sp) {Spring}
(90:\r)  node[name path=Su] (Su) {Summer}
(0:\r)   node[name path=Au] (Au) {Autumn}
(-90:\r) node[name path=Wi] (Wi) {Winter};

% How to make arrow arcs cicular? (the red one with arrow tips)
\begin{scope}[-stealth,bend left]
 \path pic{circular arc=from Sp to Su}
    pic{circular arc=from Su to Au}
    pic{circular arc=from Au to Wi}
    pic{circular arc=from Wi to Sp};

\end{scope}
\end{tikzpicture}
\end{document}

enter image description here

2
  • It works well! also it's first time I see that we can use name path in a node (but it is reasonable because a node is also a path). One of my friend is writing Asymptote code. Let's wait and compare whose code is simpler!
    – Black Mild
    Commented Oct 6, 2019 at 17:52
  • @BlackMild You can make it much shorter if you make some assumptions on the node shapes and sizes. Here you could compute the intersection points analytically, and have a super short code. The current answer works for arbitrary node shapes and sizes. What are the precise boundary conditions of this game?
    – user194703
    Commented Oct 6, 2019 at 17:59
4

This is what the graphdrawing library necklace routing is made for.

Code

% !TeX TS-program = lualatex
\documentclass[tikz]{standalone}
\usetikzlibrary{
  arrows.meta, bending,  % for Stealth arrow tips and bended arrow tips
  graphs, graphdrawing}  % for \graph syntax and \usegdlibrary → needs LuaTeX
\usegdlibrary{
  circular,        % for simple necklace layout
  routing}         % for necklace routing
\tikzgraphsset{
  circ routing/.style={
    /tikz/>={Stealth[sep,bend]},
    nodes={draw, circle},
    radius=3cm,
    ->, cycle,              % all edges are directed, last connects to first
    simple necklace layout, % place nodes on a circle
    grow'=down,             % first node is at the top, ' = clockwise
    necklace routing}}      % make connections follow the circle
\begin{document}
\tikz\graph[circ routing]{Summer, Autumn, Winter, Spring};
\end{document}

Output (with circle of radius 3cm added)

enter image description here

3

Like this?

\documentclass[border=5mm,tikz]{standalone}
\begin{document}
\begin{tikzpicture}
[every node/.style={circle,draw,fill=white}]
\def\r{3}
%\draw[red] (0,0) circle (\r);

% 4 nodes with different sizes
\path
(180:\r) node (Sp) {Spring}
(90:\r) node (Su) {Summer}
(0:\r) node (Au) {Autumn}
(-90:\r) node (Wi) {Winter};

\begin{scope}[-stealth,red,bend left]
\draw (Sp.90) to (Su.180);
\draw (Su.0) to (Au.90);
\draw (Au.270) to (Wi.0);
\draw (Wi.180) to (Sp.270);
\end{scope}
\end{tikzpicture}
\end{document}

enter image description here

1
  • It's a bit better, but still it is not circular arc (as you used [bend left] I guess)
    – Black Mild
    Commented Oct 6, 2019 at 17:25
3

I have just found a seem-to-be-simple way with angles library. Every circular arrow arc is an angle mark.

enter image description here

\documentclass[border=5mm,tikz]{standalone}
\usetikzlibrary{angles}
\begin{document}
\begin{tikzpicture}[every node/.style={circle,draw,fill=white}]
\def\r{3}
\draw[red] (0,0) circle (\r);

% 4 nodes with different sizes
\path
(0,0) coordinate (O)
(180:\r) node (Sp) {Spring}
(90:\r)  node (Su) {Summer}
(0:\r)   node (Au) {Autumn}
(-90:\r) node (Wi) {Winter};

% Make arrow arcs cicular using angles library as angle mark
\path
(Sp.north) coordinate (SpN)
(Su.west) coordinate (SuW)
pic[draw=blue,fill=none,stealth-,angle radius=\r cm]{angle=SuW--O--SpN}
(Su.east) coordinate (SuE)
(Au.north) coordinate (AuN)
pic[draw=blue,fill=none,stealth-,angle radius=\r cm]{angle=AuN--O--SuE};
\end{tikzpicture}
\end{document}
3

A short code with pstricks:

\documentclass{standalone}
\usepackage{pst-node}%

\begin{document}

    \begin{pspicture}(-3,-3)(3,3)
   \psset{unit=2, linejoin=1, arrowinset=0.1}
    \pscircle[linecolor=red](0,0){1}
    \psset{fillstyle=solid, fillcolor=white}
    \cnodeput[](1,0){A}{Autumn}
    \cnodeput(0,1){Su}{Summer}
    \cnodeput(-1,0){Sp}{Spring}
    \cnodeput(0,-1){W}{Winter}
    \foreach\S/ \T in{Su/A, A/W, W/Sp, Sp/Su}{\ncarc[arcangle=22, arrows=->]{\S}{\T}}
    \end{pspicture}

\end{document} 

enter image description here

1

I have just found another Asymptote way from this answer by Franck Pastor using firstcut and lastcut.

enter image description here

unitsize(1cm);
real R=3;
pair A=R*dir(180);
pair B=R*dir(90); 

dot(A^^B);
real rA=1, rB=1.5;
draw(circle((0,0),R),gray);
path cA=circle(A,rA);
path cB=circle(B,rB);

draw(cA^^cB);
path AB=arc((0,0),R,180,90);
draw(lastcut(firstcut(AB, cA).after, cB).before, red,arrow=Arrow(size=8));

shipout(bbox(5mm,invisible));

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .