# TikZ – Inline icons for rotations

Is there a way to create icons such as the one below using \tikz? I know there probably is a way, but I have been having trouble with getting the right positioning of the arrows and I really do not have a clue how to do this properly. I would also like to do other rotations and other polygons.

The image comes from a video by 3Blue1Brown.

I have tried the following:

\newcommand{\polyrot}[3][1ex]{\ \tikz[baseline=-3pt, inner sep=0pt] {%
\node[draw,
regular polygon,
regular polygon sides=#2,
minimum size={2 * #1},
line width=1pt] (p)
(0,0) {};
\draw [->] (0, 0) arc ({360/#2}:{360/#2 + #3}:{3 * #1});
}}


However, that just gets the positioning of the arrow completely wrong.

• Welcome to TSE. What did you try? Sep 11, 2022 at 17:12
•  \newcommand{\polyrot}[3][1ex]{\ \tikz[baseline=-3pt, inner sep=0pt] {% \node[draw, regular polygon, regular polygon sides=#2, minimum size={2 * #1}, line width=1pt] (p) (0,0) {}; \draw [->] (0, 0) arc ({360/#2}:{360/#2 + #3}:{3 * #1}); }}  is something I have tried. However, that just gets the positioning of the arrow completely wrong and I don't have any idea as to how to do better. Sep 11, 2022 at 17:28
• If you want to add something to your question, then I suggest that you edit it. Sep 11, 2022 at 17:30

Here is an automated solution. Define a macro \polyrot that takes 3 arguments, one optional:

\polyrot[<tikz options>]{<num sides>}{<rotation angle>}

tikz options can include color, scale, etc.

\documentclass{article}

\usepackage{gensymb}
\usepackage{tikz}
\usetikzlibrary {shapes.geometric, arrows.meta}

\newcommand{\polyrot}[3][]{\tikz[baseline, thick, #1]{
\node[regular polygon, regular polygon sides=#2, draw, minimum size=1cm] {};
}}

\begin{document}

\end{document}


We can measure the polygon node (or any other node when arcs around/anchor is set to a proper anchor) and use that measurement for the drawing of a few arcs around it.

The \ifnum in edge node makes sure that we only put the angle once in our diagram. With the value key arcs around/test you can specify one angle that shortens the arcs a bit.

The value of arcs around/sep will be added to the measured radius.

They main keys are arcs around/a (the list of start angles) and arcs around/d the delta angle.

## Code

\documentclass[tikz,border=5mm]{standalone}
\usetikzlibrary{calc,shapes.geometric,matrix,arrows.meta,bending}
\begin{document}
\begin{tikzpicture}[
arcs around/.code=\pgfqkeys{/tikz/arcs around}{#1},
arcs around={
.search also=/tikz,
a/.initial=0,
d/.initial=180,
test/.initial=180,
sep/.initial=1pt,
anchor/.initial=corner 1,
node/.style={
shape=rectangle, inner sep=+.1666em, auto, swap,
font=\scriptsize, node contents={$\pgfmathprintnumber{#1}^\circ$}
},
arc/.style n args={3}{
% #1 = counter, #2 = start angle, #3 = delta angle
->, draw, to path={arc[start angle=#2]\tikztonodes},
edge node/.expand once={\ifnum#1=1 node[arcs around/node=#3]\fi}
}
},
arcs around node/.style={
% #1 = list of start angles, #2 = delta angle (and text), #3 = mand. options
append after command={
% calculate radius of that circle
[arcs around={#1}]
let \p{circle} = ($(\tikzlastnode.\pgfkeysvalueof {/tikz/arcs around/anchor})-(\tikzlastnode.center)$),
{veclen(\p{circle})+\pgfkeysvalueof{/tikz/arcs around/sep}},
\n{delta} = {\pgfkeysvalueof{/tikz/arcs around/d}} in % shortcut
% common values
delta angle={\n{delta}-sign(\n{delta})*(abs(\n{delta})==
\pgfkeysvalueof{/tikz/arcs around/test}?4:0)}]
% draw arc for every angle in #1
foreach \stangle[
expand list,
count=\inlineiconcounter,
evaluate={\stAngle=\stangle+sign(\n{delta})*(abs(\n{delta})==
\pgfkeysvalueof{/tikz/arcs around/test}?2:0);}
] in {\pgfkeysvalueof{/tikz/arcs around/a}}{
edge[arcs around/arc={\inlineiconcounter}{\stAngle}{\n{delta}}]()
}
}
},
poly shape/.style={
shape=regular polygon, regular polygon sides={#1}, at={(0,0)},
fill={rgb:red,0;green,149;blue,182}, minimum size=+1cm, draw=none},
trans matrix/.style={
matrix of nodes,
nodes in empty cells,
row sep=.2em,
column sep=.4em,
% counteract any cells={nodes={<styles>}}
arcs around/node/.append style={draw=none, fill=none, minimum size=+1pt}
},
>={Stealth[scale=.8,round,bend]},
]
\matrix (m4) [
trans matrix,
arcs around/a={0,180},
cells={nodes={poly shape=4}}]{
& |[arcs around node={d= 90}]|
& |[arcs around node={d=180}]|
& |[arcs around node={d=-90, swap}]| \\
|[arcs around node={d= 90}]|
& |[arcs around node={d=180}]|
& |[arcs around node={d=-90, swap}]|
& \\
};

\matrix at (m4.south west) [
trans matrix,
anchor=north west,
yshift=-1.2em,
% triangle setup:
cells={nodes={poly shape=3}},
arcs around={
test=120,
a={0,120,240}
}
]{
& |[arcs around node={d=120}]|
& |[arcs around node={a={0,240,120}, d=240,
arc/.append style={
shift={(##2:##1*2pt)},
}}]|
& |[arcs around node={d=-120, swap}]| \\
};
\end{tikzpicture}
\end{document}


## Output

The concept node of TikZ is great! but we should not abuse node. That is an extreme use. In fact, node is just a path (with anchors).

Here is my suggestion!

\documentclass[tikz,border=2mm]{standalone}
\pagecolor{black}
\begin{document}
\begin{tikzpicture}[declare function={a=.5;startangle=-20;endangle=160;},
truncated arrow/.style={->,white,thick,shorten >=1pt,shorten <=1pt}
]
\fill[cyan] (a,a) rectangle (-a,-a);
\draw[truncated arrow] (startangle:{1.7*a}) arc(startangle:endangle:{1.7*a}) node[midway,above]{$180^{\circ}$};
\draw[truncated arrow] (endangle:{1.7*a}) arc(endangle:startangle+360:{1.7*a});
\end{tikzpicture}
\end{document}


Something like this?

\documentclass[border=10mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}

\newcommand{\polyrot}[3][1ex]{%
\tikz[baseline=-3pt, inner sep=0pt] {%
\node[draw,
regular polygon,
regular polygon sides=#2,
minimum size={2 * #1},
line width=1pt]
at (0,0) (p) {};
\pgfmathparse{360/#3}
\foreach \a in {1,...,\pgfmathresult} {
\draw[->] ({(\a - 1) * #3}:{2 * #1})
arc ({(\a - 1) * #3}:{\a * #3}:{2 * #1});
}
}}

\begin{document}

abc \polyrot{4}{180} def \polyrot{3}{90} ghi \polyrot{5}{120} jkl

\end{document}


If you want a gap between the start and the end of the arrows, you could subtract (or add) a few degrees from (or to) the start (or end) points of the arcs (I also added the labels in this example):

\documentclass[border=10mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}

\newcommand{\polyrot}[3][1ex]{%
\tikz[baseline=-3pt, inner sep=0pt] {%
\node[draw,
regular polygon,
regular polygon sides=#2,
minimum size={2 * #1},
line width=1pt]
at (0,0) {};
\pgfmathparse{360/#3}
\foreach \a in {1,...,\pgfmathresult} {
\draw[->] ({(\a - 1) * #3 + 5}:{2 * #1})
arc ({(\a - 1) * #3 + 5}:{\a * #3 - 5}:{2 * #1});
\ifnum\a=1
\node[anchor=south west, overlay] at ({min((\a * #3 * 0.5),90)}:{2.5 * #1}) {\tiny$#3^{\circ}$};
\fi
}
}}

\begin{document}

abc \polyrot{4}{180} def \polyrot{3}{90} ghi \polyrot{5}{120} jkl

\end{document}


You could also try using the option shorten > or shorten < on the arrows, which will shorten the path by the respective amount stated.

• This is nice. Just one thing I am missing is some margins on the arrows. So the tip of one arrow does not touch the tail of another Sep 11, 2022 at 18:45
• @JanMatula See my edit: You can just add (or subtract) a few degrees to (from) the arc. Sep 12, 2022 at 6:35