13

Is it possible to optimize the code below ?

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.text,calc,arrows.meta}
\begin{document}
\begin{tikzpicture}
\coordinate (O) at (0,0);
\foreach \r in {0,...,5} \draw[thick] (O) circle (0.5cm + .5cm*\r);
\draw[fill=red,draw=red] (O) circle (0.5);
\draw[fill=red,draw=red,even odd rule] (O) circle (1.5cm) circle (1cm);
\foreach \i in {0,90,180,270} \node at (\i:0.75cm) {\bf 9};
\foreach \i in {0,90,180,270} \node[white] at (\i:1.25cm) {\bf 8};
\foreach \i in {0,90,180,270} \node at (\i:1.75cm) {\bf 7};
\foreach \i in {0,90,180,270} \node at (\i:2.25cm) {\bf 6};
\foreach \i in {0,90,180,270} \node at (\i:2.75cm) {\bf 5};
\node[white] at (O) {\bf 10};
\end{tikzpicture}
\end{document}

enter image description here

3
  • 2
    What do you mean by optimize? Make it faster, make it shorter, or just improve in any way (better style, etc)? Commented Jan 3, 2018 at 23:19
  • 1
    @ShreevatsaR Make it shorter and cleaner
    – Fabrice
    Commented Jan 4, 2018 at 0:04
  • 1
    Interesting CodeReview as a tex tag.
    – Konrad
    Commented Jan 5, 2018 at 10:25

7 Answers 7

18

A bit more code golfing

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}[addlabel/.style={label={[anchor=#1]#1:\textbf{\xe}}}]
\fill[red,even odd rule] (0,0) circle (0.5) circle (1) circle (1.5);
\foreach\x[evaluate={\xe=int(10-\x)}] in {1,...,5}{
  \ifnum\x=2\relax\tikzset{text=white}\fi
  \node[minimum size=(1+\x)*1 cm,draw,circle,addlabel/.list={0,90,180,270}] {};
}
\node[circle,draw,text=white,minimum size=1cm] at (0,0) {\textbf{10}};
\end{tikzpicture}
\end{document}

enter image description here

12

Whether you like it more or not, I can't say, but it's enough with a single outer loop, and a couple of \ifnums to change the formatting. By the way,\bf has been deprecated for about 25 years.

output of code

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\foreach [count=\score from 5] \radius in {3,2.5,...,0.5}
{
\ifnum \score = 8
  \filldraw [thick,draw=black,fill=red] circle[radius=\radius cm];
  \foreach \ang in {0,90,180,270}
     \node [text=white,font=\bfseries] at (\ang:\radius cm-0.25cm) {\score};
\else
  \ifnum \score = 10
    \filldraw [thick,draw=black,fill=red] circle[radius=\radius cm];
    \node [text=white,font=\bfseries] at (0,0) {\score};     
  \else
    \filldraw [thick,draw=black,fill=white] circle[radius=\radius cm];
    \foreach \ang in {0,90,180,270}
       \node [font=\bfseries] at (\ang:\radius cm-0.25cm) {\score};
   \fi
\fi
}   
\end{tikzpicture}
\end{document}
2
  • What do you mean by \foreach[from 5] ?
    – Fabrice
    Commented Jan 4, 2018 at 10:37
  • 1
    @Fabrice Note it says count. The macro \score counts how many times the loop has run, starting the counting at 5. Commented Jan 4, 2018 at 10:43
11

Some suggestions:

  • never use \bf (it is deprecated for 25 years) and do not use it in every node
  • use one foreach loop
  • you can put the node (for the 10) at the end of the draw command

Code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.text,calc,arrows.meta}
\begin{document}
\begin{tikzpicture}[font=\bfseries]
\coordinate (O) at (0,0);
\foreach \r in {0,...,5} \draw[thick] (O) circle (0.5cm + .5cm*\r);
\draw[fill=red,draw=red] (O) circle (0.5) node[white] {10};
\draw[fill=red,draw=red,even odd rule] (O) circle (1.5cm) circle (1cm);
\foreach \i in {0,90,180,270}{
    \node at (\i:0.75cm) {9};
    \node[white] at (\i:1.25cm) {8};
    \node at (\i:1.75cm) {7};
    \node at (\i:2.25cm) {6};
    \node at (\i:2.75cm) {5};
}
\end{tikzpicture}
\end{document}
2
  • 1
    I use ConTeXt and\bf is not depreciated
    – Fabrice
    Commented Jan 4, 2018 at 0:10
  • @Fabrice You did not post ConTeXt, but LaTeX code. For ConTeXt you are absolutely right, but for LaTeX \bf is a "sin".
    – TeXnician
    Commented Jan 4, 2018 at 7:12
11

A PSTricks solution only for comparison purpose.

\documentclass[pstricks]{standalone}
\begin{document}
\pspicture(-7,-7)(7,7)
\bf{\psset{linecolor=red}\qdisk(0,0){1}\psRing*{2}{3}\rput{N}{\color{white}10}}
\foreach \i in {9,...,5}{
    \psRing{!\i/x ED 10 x sub}{!11 x sub}
    \foreach \j in {U,D,R,L}{\rput{\j}{
        \ifnum\i=8
            \rput{N}(2.5,0){\color{white}8}
        \else
            \rput{N}(+{10.5-\i},0){\i}
        \fi
    }}}
\endpspicture
\end{document}

enter image description here

0
10

Couldn't resist to draw this picture with MetaPost. The following code (included in a LuaLaTeX program) would probably benefit from some optimization as well. It uses an outer and an inner loop, and conditional instructions within.

\documentclass[border=3mm]{standalone}
\usepackage{luatex85,luamplib}
\begin{document}
\begin{mplibcode}
u=.5cm;
beginfig(1);
  for i = 6 downto 1:
    path circle; circle = fullcircle scaled (u*2i);
    if (i=3) or (i=1): fill circle withcolor red; fi
    if i=2: unfill circle; fi
    draw circle withpen pencircle scaled .8bp;
    if i>1:
        m := u*.5[i,i-1]; k := 11-i;
        for j = 0 upto 3:
            draw thelabel(TEX("\textbf{" & decimal k & "}"), m*dir(j*90))
                if i=3: withcolor white fi;
        endfor;
    else: draw thelabel(TEX("\textbf{10}"), origin) withcolor white; fi
  endfor;
endfig;
\end{mplibcode}
\end{document}

enter image description here

10

Here is a shorter code with a nested loop:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.text,calc,arrows.meta}

\begin{document}

\begin{tikzpicture}
  \coordinate (O) at (0,0);
  \foreach \r in {0,...,5} \draw[thick] (O) circle (0.5cm + .5cm*\r);
  \draw[fill=red,draw=red] (O) circle (0.5);
  \draw[fill=red,draw=red,even odd rule] (O) circle (1.5cm) circle (1cm);
  \foreach \i in {0,90,180,270}{\node[white] at (\i: 1.25) {\bfseries 8}; \foreach \r/\no in {0.75/9,1.75/7,2.25/6,2.75/5}\node at (\i:\r cm) {\bfseries \no}; };
  \node[white] at (O) {\bfseries10};;
\end{tikzpicture}

\end{document} 

enter image description here

1
  • 2
    @ArtificialStupidity: Fixed!
    – Bernard
    Commented Jan 4, 2018 at 1:02
4

Inspired by @percusse answer, here is a special type of tikz golfing, style only :

\documentclass[tikz,border=7pt]{standalone}
\begin{document}
  \tikz[inner sep=0,label distance=-2.5mm,
        r8/.style={fill=red,text=white},
        e/.style={fill=white,r#1/.try},
        l/.style 2 args={label={[anchor=center,e=#2]#1:#2}},
        s/.style={circle,draw,minimum size=(11-#1)*1cm},
        c/.style={label={[s=#1,e=#1,l/.list={{0}{#1},{90}{#1},{180}{#1},{270}{#1}}]center:}}]
      \node[c/.list={5,...,9}]{}node[s=10,r8]{10};
\end{document}

enter image description here

You must log in to answer this question.

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