# Make TikZ arrow curvier

I have this code,

\documentclass{article}

\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\draw[very thick, step = 2] (0, 0) grid (6, 6);

\node[circle, fill=blue] (a) at (2, 0) {};
\node[circle, fill=blue] (b) at (4, 0) {};

\node[circle, fill=blue] (c) at (0, 2) {};
\node[circle, fill=blue] (d) at (2, 2) {};
\node[circle, fill=blue] (e) at (4, 2) {};

\node[circle, fill=blue] (f) at (0, 4) {};
\node[circle, fill=blue] (g) at (2, 4) {};
\node[circle, fill=blue] (h) at (4, 4) {};

\path[very thick, draw=red, ->]
(a) edge node [right] {} (c)
(c) edge[bend left] node [right] {} (d)
(d) edge[bend right] node [right] {} (g)
(g) edge node [right] {} (b)
(b) edge[bend left] node [right] {} (f)
(h) edge[bend left] node [right] {} (e)
(e) edge node [right] {} (a);
\end{tikzpicture}
\end{document}


which produces the following diagram:

I have used the code from this question to make the arrows bendy, but ideally I would like the arrow that goes from node (b) to node (f) to be even curvier, and bend around the outside of the grid. What would be a good way to go about this?

Also, is there a way to create the nodes on the points of the grid, without explicitly giving the coordinates (ie. based on the size of the grid and the step size)? So that if I reshape the grid the nodes change accordingly.

Here's a method using the hobby package to draw the curve through a point off the grid.

Some notes on this code:

• I've automated the node placement by using a loop, this has added an extra node at (0,0) which could be removed if it isn't wanted but leaving it in is slightly simpler code. This also meant that I standardised the node names a little.
• Hobby curves need exact coordinates rather than node boundaries that are resolved later. Since your nodes are circles, this doesn't actually cause a problem since we can use the centre of the node to define the curve and then shorten it by a bit more than the radius of the circle.
• Obviously, the position of the coordinate that the path goes through can be customised.
• The options for the edge path should be given via every edge/.style rather than on the path itself since the purpose of the path is just for positioning and isn't intended to construct an actual path (I found this out when a strange arrow head appeared when I was trying things out)
\documentclass{article}
%\url{https://tex.stackexchange.com/q/617538/86}
\usepackage{tikz}

\usetikzlibrary{hobby}

\begin{document}
\begin{tikzpicture}
\draw[very thick, step = 2] (0, 0) grid (6, 6);

\foreach \x in {0,2,4}
\foreach \y in {0,2,4}
\node[circle, fill=blue] (grid-\x-\y) at (\x,\y) {};

\path (grid-0-0) ++(-1,-1) coordinate (a);

\path[
every edge/.style={very thick, draw=red,->}
]
(grid-2-0) edge (grid-0-2)
(grid-0-2) edge[bend left] (grid-2-2)
(grid-2-2) edge[bend right] (grid-2-4)
(grid-2-4) edge (grid-4-0)
(grid-4-0.center) edge[shorten <=5pt,shorten >=5pt,curve through=(a)] (grid-0-4.center)
(grid-4-4) edge[bend left] (grid-4-2)
(grid-4-2) edge (grid-2-0);

\end{tikzpicture}
\end{document}


\documentclass{article}

\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\draw[very thick, step = 2] (0, 0) grid (6, 6);

\node[circle, fill=blue] (a) at (2, 0) {};
\node[circle, fill=blue] (b) at (4, 0) {};

\node[circle, fill=blue] (c) at (0, 2) {};
\node[circle, fill=blue] (d) at (2, 2) {};
\node[circle, fill=blue] (e) at (4, 2) {};

\node[circle, fill=blue] (f) at (0, 4) {};
\node[circle, fill=blue] (g) at (2, 4) {};
\node[circle, fill=blue] (h) at (4, 4) {};

\path[very thick, draw=red, ->]
(a) edge node [right] {} (c)
(c) edge[bend left] node [right] {} (d)
(d) edge[bend right] node [right] {} (g)
(g) edge node [right] {} (b)
(b) edge[out=245, in=180, looseness=2] node [right] {} (f)
(h) edge[bend left] node [right] {} (e)
(e) edge node [right] {} (a);
\end{tikzpicture}
\end{document}


EDIT

Just a matter of adjusting the outwards angle from b as 225 degrees and the inwards angle at f as 225 degrees, the looseness controls the flexibility of the curve -- feel free to experiment

\documentclass{article}

\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\draw[very thick, step = 2] (0, 0) grid (6, 6);

\node[circle, fill=blue] (a) at (2, 0) {};
\node[circle, fill=blue] (b) at (4, 0) {};

\node[circle, fill=blue] (c) at (0, 2) {};
\node[circle, fill=blue] (d) at (2, 2) {};
\node[circle, fill=blue] (e) at (4, 2) {};

\node[circle, fill=blue] (f) at (0, 4) {};
\node[circle, fill=blue] (g) at (2, 4) {};
\node[circle, fill=blue] (h) at (4, 4) {};

\path[very thick, draw=red, ->]
(a) edge node [right] {} (c)
(c) edge[bend left] node [right] {} (d)
(d) edge[bend right] node [right] {} (g)
(g) edge node [right] {} (b)
(b) edge[out=225, in=225, looseness=2] node [right] {} (f)
(h) edge[bend left] node [right] {} (e)
(e) edge node [right] {} (a);
\end{tikzpicture}
\end{document}


• Thanks for your answer! Is there a way to make it so that the arrow has constant curvature? Oct 2, 2021 at 18:42
• @Zarathustra please see edit above Oct 2, 2021 at 23:46
• @Zarathustra what do you mean "constant curvature"? Oct 3, 2021 at 1:18
• @BlackMild He is saying something like this, the arrow should be a arc of a perfect circle, while the arrows start and end points are on the circle which possess the arc/arrow. if not, something like this, if I draw a straight-line/shortest-line from the arrow end point and the start point, the space between any point of the arrow and the middle point of the drawn line should be always equal. Or simply this: i.stack.imgur.com/Uy8bL.png Oct 4, 2021 at 6:40

I use the controls operation to get full controls curvy curves. control works for both coordinate and node. All other operations to, --, to[bend left], ... are special cases of controls.

Some explaination: Imagine we shoot from shooting point (b) with shooting angle -150 and shooting force 2; shoot from shooting point (f) with shooting angle -120 and shooting force 2.

(b) ..controls +(-150:2) and +(-120:2) .. (f)


\documentclass[tikz,border=10mm]{standalone}
\begin{document}
\begin{tikzpicture}[scale=2]
\draw[very thick] (0,0) grid (3,3);

\foreach \p/\pname in {(1,0)/a,(2,0)/b,(0,1)/c,(1,1)/d,(2,1)/e,(0,2)/f,(1,2)/g,(2,2)/h}
\path \p node[circle,fill=blue,text=white] (\pname){};

\begin{pgfinterruptboundingbox} % prevent bounding box larger when using controls
\begin{scope}[very thick,red]
\draw[->] (h) to[bend left] (e);
\draw[->] (e) to[bend right] (a);
\draw[->] (a) to[bend left] (c);
\draw[->] (c) to[bend left] (d);
\draw[->] (d) to[bend left] (g);
\draw[->] (g) to (b);
\draw[->] (b) ..controls +(-150:2) and +(-120:2) .. (f);
\end{scope}
\end{pgfinterruptboundingbox}
\end{tikzpicture}
\end{document}