Triangular numbers in TikZ

I need to draw an image of the first three triangular numbers inscribed in a square.

Now, I have two problems constructing this image.

• Construct the circles perfectly centered

It is acceptable to answer only my first question (in order to correspond to the one question, one post policy) although I would be glad if someone answered both.

Now I have no minimal example, but in order to construct this image any packages would suffice, although my preference is for TikZ.

I am using a variety of packages, although I doubt any of them would interfere in the construction of this image.

• Does anyone have any tips or suggestions for how to construct the first n triangular numbers inside a square (with "correct" shading)?
-
Looks like golf balls on a blue background. –  Marco Daniel Dec 9 '11 at 13:26
By "shading" do you mean the shadows that each casts on the others, or just a colouring of the balls themselves to give a 3d effect. –  Loop Space Dec 9 '11 at 14:12
Both prefferably, if this is too much work. Just the latter =) –  N3buchadnezzar Dec 9 '11 at 14:23
Before I post an answer that may be pointless, does this look horrible? –  Torbjørn T. Dec 9 '11 at 15:07
It looks good =) Other than the colours are wrong (I gueess grey and white would be better?). Impressive ^^ –  N3buchadnezzar Dec 9 '11 at 15:25

Try something like:

\documentclass{article}
\usepackage{tikz}

\newcommand\drawballs[2][]{%
\foreach \y [evaluate=\y as \yy using #2+1-\y] in {1,...,#2} {%
\foreach \x in {1,...,\yy} {%
};
}%
}

\begin{document}

\begin{tikzpicture}
\drawballs{1}
\drawballs[xshift=2cm]{2}
\drawballs[xshift=5cm]{3}
\end{tikzpicture}

\end{document}


-
+1; much the cleanest and clearest of the answers offered. –  Peter LeFanu Lumsdaine Dec 9 '11 at 18:07
Yes good method –  Alain Matthes Dec 9 '11 at 23:06

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 scopes.

There is some shifty 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}

\newcommand{\trianglenumber}[1]{%
\node[ball,yshift=0.45cm*#1] (p-0-0) at (0,0) {};
\foreach \row in {1,...,#1} {
% col #0 =&gt; 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,
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}


-

You can do this straight in TikZ. Here's a reasonably complete sample that has some arbitrary default options to control the appearance. You can make triangles of any size, too:

\documentclass{article}
\usepackage{tikz}

}

\newcommand\triangleloweredge[1]{% #1 = length
\foreach \n [evaluate = \n using \n - 1] in {1,...,#1} {
}
}

\newcommand\triangleofballs[1]{% #1 = side length
\foreach \m [count = \c from 0] in {#1,...,1} {
\tikzset{shift = {(60:2*\c)}}
\triangleloweredge{\m}
}
}

\newcommand\squaredtriangleofballs[2][]{% #1 = global options, #2 = side length
\begin{scope}[#1]
\path[square border] (0,0) rectangle (${2*(#2)}*(1,1)$);
\node[anchor = south west, inner sep = 0] {\tikz[shaded ball, #1] \triangleofballs{#2};};
\end{scope}
}

\tikzset{
square border/.style = {
draw, ultra thick, red, fill = gray
},
color = violet, ball color = green
}
}

\begin{document}
\begin{tikzpicture}
\squaredtriangleofballs[scale = 0.75]{3}
\end{tikzpicture}
\end{document}


Sort of like Martin Heller's response, which I see appeared while I was testing. It may have some slight advantages in the programming: it uses the polar coordinate system rather than coordinate computations, uses a "lemma" for each part of the operation, and does everything with TikZ options rather than TeX macros/dimensions. I also give one possible way to draw the box; in this new version, it draws an actual square, not the fitting rectangle.

-
Well, I'm nearly embarrassed by my own answer ... This should definitely have more votes than mine. –  Torbjørn T. Dec 9 '11 at 19:00

Update version with tkz-euclide with square

It's possible to write a code more concise but it's difficult to get something better than Martin' code. I use the same ideas of my first code.

\documentclass[11pt]{scrartcl}
\usepackage{tkz-euclide}
\usetkzobj{all}

\begin{document}

\newcommand{\ballgolf}[1]{
\begin{tikzpicture}
\tkzDefPoint(1,-1){S1}
\tkzDefPoint(#1*2+1,-1){S2}
\tkzDrawSquare[fill=blue!30!black](S1,S2)
\foreach \i in {1,...,#1}{%
\tkzDefPoint(2*\i,0){O\i}
\tkzDrawCircle[R,ball color=gray!20](O\i,1cm)}
\ifnum #1=1 \else
\foreach \j [evaluate=\j as \j ] in {#1-1,...-1,2-1}{%
\foreach \i in {1,...,\j}{%
\tkzDefShiftPoint[O\i](60:2){O\i}
\tkzDrawCircle[R,ball color=gray!20](O\i,1cm)
}%
}%
\fi
\end{tikzpicture}}

\ballgolf{1} \ballgolf{2} \ballgolf{3}
\end{document}


Same version with tikz

\documentclass[11pt]{scrartcl}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}

\newcommand{\ballgolf}[1]{
\begin{tikzpicture}
\draw[fill=blue!30!black] (1,-1) rectangle (#1*2+1,#1*2-1);
\foreach \i in {1,...,#1}{%
\coordinate (O\i) at  (2*\i,0);
\draw[ball color=gray!20] (O\i) circle(1cm);}
\ifnum #1=1 \else
\foreach \j [evaluate=\j as \j ] in {#1-1,...-1,2-1}{%
\foreach \i in {1,...,\j}{%
\coordinate (O\i) at  ($(O\i)+(60:2)$);
\draw[ball color=gray!20] (O\i) circle(1cm);
}%
}%
\fi
\end{tikzpicture}
}%

\ballgolf{1} \ballgolf{2} \ballgolf{3}
\end{document}

-
I forgot the square but it's not very diffcult –  Alain Matthes Dec 9 '11 at 16:00

I forgot that I created tkz-berge

\documentclass[11pt]{scrartcl}
\usepackage{tkz-berge}

\newcommand{\ballgolf}[1]{%
\SetVertexNoLabel
\foreach \i [evaluate=\i as \j using #1-\i] in {0,...,\number\numexpr#1 - 1\relax}{%
\pgfmathsetmacro\k{\i*sqrt(3)/2}
\begin{scope}[shift={(\i*.5 cm,\k cm)}]
\grEmptyPath[RA=1]{\j}
\end{scope}}}

\begin{document}
\tikzset{VertexStyle/.style ={circle,ball color= gray!80!yellow,minimum size = 1cm}}
\tikz{\ballgolf{4}}
\end{document}


The same but only with tikz

\documentclass[11pt]{scrartcl}
\usepackage{tikz}

\newcommand{\ballgolftikz}[1]{%
\foreach \i  in {0,...,\number\numexpr#1 - 1\relax}{%
\pgfmathsetmacro\k{\i*sqrt(3)/2}
\begin{scope}[shift={(\i*.5 cm,\k cm)}]
\foreach \t in {1,...,\number\numexpr #1-\i\relax}{
\shade[ball color= gray] (\t,0) circle (.5cm);}
\end{scope}}
}
\begin{document}
\tikz{\ballgolftikz{3}}
\end{document}

-