# Move graph nodes on a circular path while keeping the circle

I would like to show nodes on a graph. The graph shape should be a circle. I would like to move the nodes while keep the circular shape. The following is what I can create with four nodes and it actually looks good:

\tikzstyle{cblue}=[circle, draw, thin,fill=cyan!20, scale=0.5]

\begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=3cm,thick,main node/.style={rectangle,fill=blue!20,draw,font=\sffamily\Large\bfseries}]
\draw[help lines] (-1,-1) grid (1,1);
\node[cblue] (1) at ( 90:1 ) {1};
\node[cblue] (2) at ( 0:1 ) {2};
\node[cblue] (3) at ( -90:1) {3};
\node[cblue] (4) at ( 180:1) {4};

\path[every node/.style={font=\sffamily\small}]
(1) edge  [bend left]  node [right] {} (2)
(2) edge  [bend left]  node [right] {} (3)
(3) edge  [bend left]  node [right] {} (4)
(4) edge  [bend left]  node [right] {} (1) ;
\end{tikzpicture}


However, as I move the nodes along the circle, the circular shape is not preserved. Here are some modified coordinates:

\node[cblue] (1) at ( 90:1 ) {1};
\node[cblue] (2) at ( 30:1 ) {2};
\node[cblue] (3) at ( 340:1) {3};
\node[cblue] (4) at ( 180:1) {4};


I guess this is because as explained here, bend right option is not exactly a circular pattern.

I have looked into pgf's "through library" and though I could draw a circle that passes through the nodes, but what I really want is a circle that is broken into four pieces, each piece separated by two nodes.

I appreciate if someone could tell me how I can do this?

If you don't mind parameterizing a bunch of stuff (including the scale) the arcs can be drawn fairly precisely, by calculating the angle on the main circle subtended by the chord formed by the radii of the nodes.

There will still be a slight error in the arcs caused by pgf "backing-up" along the tangent of the endpoint of the arc. In the CVS version of pgf the bending library (not used here) can overcome this.

\documentclass[border=0.125cm]{standalone}

\usepackage{tikz}
\usetikzlibrary{decorations.markings}

\begin{document}

\def\s{2}% scaling factor
\def\o{1pt}% outer sep
\def\shO{0}% shorten angle out
\def\shI{2}% shorten angle in

% chord angle = 2*asin(R/(2*r))
%
% Here the radius R must also include the outer sep
% and the radius r must include the scaling factor
%
\pgfmathparse{2*asin((\R+\o)/(2*\r*\s))+\shO}\let\aO=\pgfmathresult
\pgfmathparse{2*asin((\R+\o)/(2*\r*\s))+\shI}\let\aI=\pgfmathresult

\begin{tikzpicture}[scale=\s, cblue/.style={circle, draw, fill=cyan!20, font=\footnotesize, outer sep=\o, minimum size=\R*2}, >=stealth]

\draw [ultra thick, gray!50] circle [radius=\r];

\node[cblue] (1) at ( 90:\r ) {1};
\node[cblue] (2) at ( 30:\r ) {2};
\node[cblue] (3) at ( 340:\r) {3};
\node[cblue] (4) at ( 180:\r) {4};

% By default there will still be an error
% in the paths due to PGF backing up'
% to draw the arrow head.
\draw [->] (90-\aO:\r)  arc (90-\aO:30+\aI:\r);
\draw [->] (30-\aO:\r)  arc (30-\aO:-20+\aI:\r);
\draw [->] (340-\aO:\r) arc (340-\aO:180+\aI:\r);
\draw [->] (180-\aO:\r) arc (180-\aO:90+\aI:\r);

\end{tikzpicture}

\end{document}


• I didn't quiet understand the math for calculating aO and aI. As I change the scale, their values are not calculated correctly. But I was able to play with shO and shI and fix them. Thank you for the solution.
– Ari
Dec 17, 2013 at 23:23

Using bend left won't be useful here. But use of in and out angles with carefully chosen looseness may help. Adjust them to suit your needs.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows}
\tikzset{cblue/.style={circle, draw, thin,fill=cyan!20, scale=0.5}}

\begin{document}
\begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=3cm,thick,main node/.style={rectangle,fill=blue!20,draw,font=\sffamily\Large\bfseries}]
\draw[help lines] (-1,-1) grid (1,1);
\draw[gray] (0,0) circle (1cm);
\node[cblue] (1) at ( 90:1 ) {1};
\node[cblue] (2) at ( 30:1 ) {2};
\node[cblue] (3) at ( 340:1) {3};
\node[cblue] (4) at ( 180:1) {4};

\path[every node/.style={font=\sffamily\small}]
(1) edge  [in=125,out=0,looseness=.7]  node [right] {} (2)
(2) edge  [in=80,out=-65,looseness=.85]  node [right] {} (3)
(3) edge  [in=280,out=-115,looseness=1.25]  node [right] {} (4)
(4) edge  [in=185,out=90,looseness=.8]  node [right] {} (1) ;
\end{tikzpicture}
\end{document}


• I need to place the nodes so that there is one at 90, one at 30, one at -20, and one at 180 degrees. Simply rotating the entire picture cannot achieve this.
– Ari
Dec 17, 2013 at 0:07
• @Ari I misunderstood then. See the edit.
– user11232
Dec 17, 2013 at 0:15
• Thanks @Harish! Should I find the in/out and looseness values by trial and error for different angles? Do you think there is a way to come up with a general formula for nodes at arbitrary angles?
– Ari
Dec 17, 2013 at 0:25
• @Ari How precise do you want it to be? You could calculate the exact point where the lines would start and end but the shorten > amount would skew it anyway (because it shortens on a straight line not along the path). The intersections library can always help but makes the solution much longer. Dec 17, 2013 at 0:27
• I just need it to visually look like a circle.
– Ari
Dec 17, 2013 at 0:57

It seems that the focal point is to keep the circle reserved when nodes are moved along the circle. To this end, this attempt proposes arccommands.

\draw (alpha:radius) arc (alpha:beta:radius);  % alpha=start angle, beta=end angle


Code:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows}
\tikzset{cblue/.style={circle, draw, thin,fill=cyan!20, scale=0.5}
}

\begin{document}
\begin{tikzpicture}[->,>=stealth',shorten >=5pt,auto,thick, scale=2]
\draw [help lines] (-1,-1) grid (1,1);
\draw (90:1)     arc (90:30:1);
\draw (30:1)     arc (30:-20:1);
\draw (-20:1)    arc (-20:-180:1);
\draw (-180:1)   arc (-180:-270:1);
\node[cblue] (1) at ( 90:1 ) {1};
\node[cblue] (2) at ( 30:1 ) {2};
\node[cblue] (3) at ( 340:1) {3};
\node[cblue] (4) at ( 180:1) {4};
\end{tikzpicture}

\hspace{1cm}

\begin{tikzpicture}[->,>=stealth',shorten >=5pt,auto,thick,scale=2]
\draw[help lines] (-1,-1) grid (1,1);
\draw (120:1)    arc (120:30:1);
\draw (30:1)     arc (30:-60:1);
\draw (-60:1)    arc (-60:-200:1);
\draw (-200:1)   arc (-200:-240:1);
\node[cblue] (1) at ( 120:1 ){1};
\node[cblue] (2) at ( 30:1 )  {2};
\node[cblue] (3) at ( 300:1) {3};
\node[cblue] (4) at ( 160:1) {4};
\end{tikzpicture}
\end{document}
`