Fill a square with circles in Tikz

tikz-pgf

I am aiming to draw a square with circles – starting in the bottom left corner of the square the radius and the position of the subsequent circles (of course multiplied by the respective loop variable to move it one step further in each step) is the length of one side of the square divided by the number of circles. My current example still runs the loop one step to far because I still try to find the prettiest way to reduce circles by 1.

\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (4,0);
\coordinate (c) at (4,4);
\coordinate (d) at (0,4);
\def\circles{5}

\draw[gray, thick] (a) -- (b) -- (c) -- (d) -- (a);
\tikzmath{
    coordinate \c;
    \c = (b) - (a);
    \length = sqrt((\cx) ^ 2 + (\cy) ^ 2) / \circles; 
    \radius = \length / 2; 
}
\foreach \i in {0,...,\circles}
{
    \pgfmathtruncatemacro{\x}{\i * \length};
    \foreach \j in {0,...,\circles}
    {
        \pgfmathtruncatemacro{\y}{\j * \length};
        % \draw[gray, thick] (\x, \y) circle[radius=\radius pt];
        \draw[gray, thick] (\x pt, \y pt) circle[radius=\radius pt]; % proposed fix by AndrewStacey - still I don't understand why the radius is also fixed by a fix of the position of each circle
    }
}
\end{tikzpicture}

As result I would expect to get the number of circles squared and touching each other laying on the border of the square as well as inside it. I guess that there is something weird happening with computed distances but I neither know is happening nor how to fix it.

enter image description here

using pt as stated by Andrew Stacey leads to the following result:

enter image description here

this is a lot better. Still I would like to achieve the optimal result where the circles each touching in one point and the centers are perfectly aligned. I guess the error happens because of some problem with tikz only using integer and my solution relying on floats. Still I don't know how to do it better.

Best Answer

The circles are the wrong size because \tikzmath works in pt but the numbers are returned as just numbers, so \radius is a bare number which is the desired radius as measured in pt. Then when you use a coordinate like (\x, \y), these are just numbers so are interpreted in the current coordinate axes. With no transformations in place then these are cm. So your numbers are too big. Using (\x pt, \y pt) says that the numbers are to be interpreted as pt.

Then there is an issue with the calculations inside the loops. By using \pgfmathtruncatemacro you are rounding your answers. Either use \pgfmathsetmacro, or you can do the calculation via an evaluate key on the \foreach.

\documentclass{article}
%\url{https://tex.stackexchange.com/q/620551/86}
\usepackage{tikz}
\usetikzlibrary{math}

\begin{document}

\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (4,0);
\coordinate (c) at (4,4);
\coordinate (d) at (0,4);
\def\circles{5}

\draw[gray, thick] (a) -- (b) -- (c) -- (d) -- (a);
\tikzmath{
    coordinate \c;
    \c = (b) - (a);
    \length = sqrt((\cx) ^ 2 + (\cy) ^ 2) / \circles; 
    \radius = \length / 2; 
}

\foreach[evaluate=\i as \x using \i * \length]
\i in {0,...,\circles}
{
%    \pgfmathsetmacro{\x}{\i * \length}
  \foreach[evaluate=\j as \y using \j * \length]
  \j in {0,...,\circles}
    {
%        \pgfmathsetmacro{\y}{\j * \length}
        \draw[gray, thick] (\x pt, \y pt) circle[radius=\radius pt];
    }
}
\end{tikzpicture}

\end{document}

grid of circles in a square

Related Question