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

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

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}
  • What do you mean by \foreach[from 5] ? – Fabrice Jan 4 '18 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. – Torbjørn T. Jan 4 '18 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}
  • 1
    I use ConTeXt and\bf is not depreciated – Fabrice Jan 4 '18 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 Jan 4 '18 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

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

  • 2
    @ArtificialStupidity: Fixed! – Bernard Jan 4 '18 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

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.