You could adapt the example with Pascal's triangle. The below is not perfect, and the alignment could be done more elegantly, but it's a start.
A big thanks goes of course to Paul Gaborit, for doing the hard work.
The grid is added to make it easier to see how they are aligned in relation to each other. I tried calculating the xshift
and including that into \trianglenumber
, but my initial attempt failed miserably, hence the manual shifting with scope
s.
There is some shift
y stuff going on. I removed the little space between the rows by adding +\row*0.1
at two places, for the y
-coordinate (the 0.1 value vas just a lucky guess):
\node[ball,yshift=0.45cm*#1] (p-\row-0) at (-\row/2,-\row+\row*0.1) {};
and in
\coordinate (pos) at (-\row/2+\col,-\row+\row*0.1+0.45*#1);
Further, to have them aligned vertically by their centers, the second and third are shifted by 0.45cm*<number of additional rows>
. As the argument to \trianglenumber
defines just the number of additional rows, you see this in the two lines above, in the option for the node – yshift=0.45cm*#1
– and in the y
-coordinate of pos
– +0.45*#1
.
Not very elegant perhaps, but it mostly does the job.
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning,shadows,backgrounds,calc}
\newcommand{\trianglenumber}[1]{%
\node[ball,yshift=0.45cm*#1] (p-0-0) at (0,0) {};
\foreach \row in {1,...,#1} {
% col #0 => value is 1
\node[ball,yshift=0.45cm*#1] (p-\row-0) at (-\row/2,-\row+\row*0.1) {};
\pgfmathsetmacro{\value}{1};
\foreach \col in {1,...,\row} {
% iterative formula : val = precval * (row-col+1)/col
% (+ 0.5 to bypass rounding errors)
\pgfmathtruncatemacro{\value}{\value*((\row-\col+1)/\col)+0.5};
\global\let\value=\value
% position of each value
\coordinate (pos) at (-\row/2+\col,-\row+\row*0.1+0.45*#1);
\pgfmathtruncatemacro{\rest}{mod(\value,2)}
\ifnum \rest=0
\node[ball] (p-\row-\col) at (pos) {};
\else
\node[ball] (p-\row-\col) at (pos) {};
\fi
}
}
}
% some styles
\tikzset{
ball/.style={
minimum size=10mm,
draw=black,
circle,
shade=ball,
ball color=gray!20,
},
}
\begin{document}
\centering
\begin{tikzpicture}
\begin{scope}
\node [ball] {};
\end{scope}
\begin{scope}[xshift=2.5cm]
\trianglenumber{1}
\end{scope}
\begin{scope}[xshift=6cm]
\trianglenumber{2}
\end{scope}
\draw (current bounding box.south west) grid (current bounding box.north east);
\end{tikzpicture}
\end{document}
