Drawing stars/similar with Tikz

Here's the code for fully filled stars, now slightly improved thanks to Andrew Stacey's answer to the checkerboard question:

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}

\newcommand\score[2]{%
  \pgfmathsetmacro\pgfxa{#1 + 1}%
  \tikzstyle{scorestars}=[star, star points=5, star point ratio=2.25, draw, inner sep=1.3pt, anchor=outer point 3]%
  \begin{tikzpicture}[baseline]
    \foreach \i in {1, ..., #2} {
      \pgfmathparse{\i<=#1 ? "yellow" : "gray"}
      \edef\starcolor{\pgfmathresult}
      \draw (\i*1.75ex, 0) node[name=star\i, scorestars, fill=\starcolor]  {};
   }
  \end{tikzpicture}%
}

\begin{document}
\score{0}{5} A meagre result.

\score{4}{5} Much better

\score{5}{5} Perfect score!

\end{document}

ranking stars with tikz


And here's the much more elaborate, much more pointless, floating point scoring star macro (I'll leave the simple one in as well, it's a lot more usable):

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric, calc}

\newcommand\score[2]{%
  \pgfmathsetmacro\pgfxa{#1 + 1}%
  \tikzstyle{scorestars}=[star, star points=5, star point ratio=2.25, draw, inner sep=0.15em, anchor=outer point 3]%
  \begin{tikzpicture}[baseline]
    \foreach \i in {1, ..., #2} {
      \pgfmathparse{\i<=#1 ? "yellow" : "gray"}
      \edef\starcolor{\pgfmathresult}
      \draw (\i*1em, 0) node[name=star\i, scorestars, fill=\starcolor]  {};
    }
    \pgfmathparse{#1>int(#1) ? int(#1+1) : 0}
    \let\partstar=\pgfmathresult
    \ifnum\partstar>0
      \pgfmathsetmacro\starpart{#1-(int(#1)}
      \path [clip] ($(star\partstar.outer point 3)!(star\partstar.outer point 2)!(star\partstar.outer point 4)$) rectangle 
      ($(star\partstar.outer point 2 |- star\partstar.outer point 1)!\starpart!(star\partstar.outer point 1 -| star\partstar.outer point 5)$);
      \fill (\partstar*1em, 0) node[scorestars, fill=yellow]  {};
    \fi
  \end{tikzpicture}%
}

\begin{document}
\score{0}{5} That's appalling!

\small\score{2}{5} A meagre result.

\Huge{\score{4.4}{5} Wooo!}

\end{document}

enter image description here


enter image description here

Asymptote version stars.asy:

size(200);
real sc=20;

picture score(real scoreMark=0,guide star=scale(sc)*unitcircle, int maxscore=5, 
  pen linePen=nullpen, pen bgPen=darkblue, pen scorePen=orange){
  picture pic;
  guide[] g;  
  for(int i=0;i<maxscore;++i){
    g.push(shift((2sc*i,0))*star);
  }
  assert(maxscore>0 && scoreMark>=0 && scoreMark<=maxscore,"***** Wrong score.");
  fill(pic,box((-sc,-sc),(maxscore*2sc-sc,sc)),bgPen);
  fill(pic,box((-sc,-sc),(scoreMark*2sc-sc,sc)),scorePen);
  clip(pic,g);
  draw(pic,g,linePen);
  return pic;
}

guide star;
pair p;
for(int i=0;i<5;++i){
  p=rotate(72*i)*N;
  star=star--p;
  star=star--(scale(0.382)*rotate(72*i+36)*N);
}
star=scale(sc)*(star--cycle);

add(score(scoreMark=1,star,maxscore=7),(0,0));
add(score(scoreMark=2,star,maxscore=7,linePen=lightred,bgPen=lightblue),(0,-3sc));
add(score(scoreMark=3.5,star,maxscore=5,linePen=lightred,bgPen=lightblue),(0,-6sc));
add(score(scoreMark=3.75,star,maxscore=4,linePen=olive,bgPen=white,scorePen=lightgreen),(0,-9sc));

add(score(4.2,bgPen=green+opacity(0.3),scorePen=red+opacity(0.5)),(0,3sc));

To get a standalone stars.pdf run asy -f pdf stars.asy.


With PSTricks.

enter image description here

\documentclass[preview,border=12pt,varwidth]{standalone}
\usepackage{pstricks}
\usepackage{multido}
\SpecialCoor
\makeatletter
\def\LoadPSVars{\pstVerb{/ptcm {\pst@number\psunit div} bind def}}
\makeatother

\def\points{}
\def\Star{%
    \xdef\points{}% cleaning
    \multido{\iR=0+72,\ir=36+72}{5}{\xdef\points{\points (10pt;\iR)(5pt;\ir)}}
    \expandafter\pspolygon\points}

\def\Rating#1{% #1: percentage
    \psscalebox{0.35}{%
    \begin{pspicture}(11pt,-11pt)(111pt,11pt)
    \LoadPSVars
    \psclip{\pscustom{\psLoop{5}{\translate(20pt,0)\Star}}}
        \psframe*[linecolor=yellow](11pt,-11pt)(!#1 11 add ptcm 11 ptcm)
    \endpsclip
    \pscustom{\psLoop{5}{\translate(20pt,0)\Star}}
    \end{pspicture}}}

\begin{document}
\begin{enumerate}
    \item \Rating{100} PSTricks
    \item \Rating{50} Asymptote
    \item \Rating{20} Metapost
    \item \Rating{5} TikZ
\end{enumerate}
\end{document}

Warning:

  • \rput will not work inside \pscustom. Use \translate instead!
  • standalone discards my ptcm operator defined in the preamble, so I have to load it manually inside pspicture. It is sad!