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}
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}
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.
\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 myptcm
operator defined in the preamble, so I have to load it manually insidepspicture
. It is sad!