Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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

The first three triangular numbers

Now, I have two problems constructing this image.

  • Construct the circles perfectly centered
  • The shading

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)?
share|improve this question
    
Looks like golf balls on a blue background. –  Marco Daniel Dec 9 '11 at 13:26
1  
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
add comment

5 Answers

up vote 25 down vote accepted

Try something like:

\documentclass{article}
\usepackage{tikz}

\newlength\radius
\pgfmathsetlength{\radius}{0.5cm}
\newcommand\drawballs[2][]{%
    \foreach \y [evaluate=\y as \yy using #2+1-\y] in {1,...,#2} {%
        \foreach \x in {1,...,\yy} {%
            \shade[shading=ball,ball color=white,#1] 
                ({(2*\x-2+\y)*\radius},{sqrt(3)*\y*\radius}) circle (\radius); 
        };
    }%
}

\begin{document}

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

\end{document}

output of code

share|improve this answer
    
+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
add comment

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}
\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 =&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,
      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}

enter image description here

share|improve this answer
add comment

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}
\usetikzlibrary{shadings,calc}

\newcommand\shadedball[1]{% #1 = (coordinates)
 \shadedraw [shading = ball] #1 circle [radius = 1]
}

\newcommand\triangleloweredge[1]{% #1 = length
 \foreach \n [evaluate = \n using \n - 1] in {1,...,#1} {
  \shadedball{(2*\n,0)};
 }
}

\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
 },
 shaded ball/.style = {
  color = violet, ball color = green
 }
}

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

enter image description here

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.

share|improve this answer
    
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
add comment

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} 

enter image description here

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}
share|improve this answer
    
I forgot the square but it's not very diffcult –  Alain Matthes Dec 9 '11 at 16:00
add comment

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} 

enter image description here

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}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.