6

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.

An example of a graphic I would like to replicate

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.

3
  • 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.
    – Jan Matula
    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

4 Answers 4

5

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.

enter image description here

\documentclass{article}

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

\newcommand{\circrad}{.6}
\newcommand{\polyrot}[3][]{\tikz[baseline, thick, #1]{
    \node[regular polygon, regular polygon sides=#2, draw, minimum size=1cm] {}; 
    \draw[-{Triangle[angle=60:3pt]}] (5:\circrad) arc (5:#3:\circrad);
    \node at (#3/2:1.4*\circrad){\scriptsize#3\degree};
    \draw[-{Triangle[angle=60:3pt]}] (185:\circrad) arc (185:180+#3:\circrad);
}}

\begin{document}

\polyrot{3}{120}\quad\polyrot{4}{90}\quad\polyrot{4}{180}\quad\polyrot{4}{-90}\quad\polyrot{5}{144}

\end{document}
4

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)$),
          \n{radius} =
                  {veclen(\p{circle})+\pgfkeysvalueof{/tikz/arcs around/sep}},
          \n{delta} = {\pgfkeysvalueof{/tikz/arcs around/d}} in % shortcut
      % common values
      [radius=\n{radius},
       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}}{
          ([shift=(\stAngle:\n{radius})]\tikzlastnode.center)
            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)},
        radius/.expanded=\pgfkeysvalueof{/tikz/x radius}+##1*2pt
      }}]|
  & |[arcs around node={d=-120, swap}]| \\
};
\end{tikzpicture}
\end{document}

Output

enter image description here

0
3

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!

enter image description here

\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}
2

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}

enter image description here

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}

enter image description here

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

2
  • 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
    – Jan Matula
    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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.