# How to automatically calculate parameters of a TikZ repeating pattern?

I am a beginner in LaTeX and TikZ, trying to make industrial documents, containing a series of terminal block whose wiring is shown in the MWE. I have to make a sereis of these dwawings. The envelope is the same, but the size of the pins, the number of row and the spacing between rows changes. I have tried to put the useful parameters in a macro, in order to easily generate each configuration. However I could not solve the last step, ie automatically calculating the last numbers such as the number 12, in the foreach statements, ie #3-1, which is the number of cavities of the row containing an even number. I could not find a way either to calculate the numbers of the last pins of each row, ie 25, 38,50, that are needed to start the numbering of the next rows. I doubt also that this code is optimized, and would welcome any tip to improve it.

\documentclass{standalone}
\usepackage{tikz}
\begin{document}

\newcommand{\DrawTerminalBlock}[5]{
\begin{tikzpicture}[scale=#1, thick,
mynode/.style={circle, draw, very thin, minimum size=2.6mm, text centered,font=\tiny, inner sep=0.5pt},
]
\coordinate (O) at (0,0) ;
\coordinate (A) at (1.495,0) ;
\coordinate (B) at (1.495, 0.684) ;
\coordinate (C) at (1.309,.870) ;
\coordinate (D) at (0.208,0.870) ;
\coordinate (E) at (0,0.684) ;
\draw (O) --(A) --(B)--( C)-- (D) --(E) --(O)--cycle; %Draw outline
% #1 Scale
% #2 Horizontal spacing between cavities
% #3 Number of horizontal cavities long rows (odd number of cavities)
% #4 Vertical distance to lower (bottom) row
% #5 Vertical spacing between rows

\foreach \x in {1,...,#3}
{
\node[mynode,] at (#2*\x, #4) {\x};
}
\foreach \x in {1,...,12}
{\pgfmathparse{int(#3+\x)}
\edef\n{\pgfmathresult}
\node[mynode,] at (0.5*#2+#2*\x,#4+#5) {\n};
}
\foreach \x in {1,...,#3}
{\pgfmathparse{int(25+\x)}
\edef\n{\pgfmathresult}
\node[mynode,] at (#2*\x,#4+2*#5) {\n};
}
\foreach \x in {1,...,12}
{\pgfmathparse{int(38+\x)}
\edef\n{\pgfmathresult}
\node[mynode,] at (0.5*#2+#2*\x,#4+3*#5) {\n};
}
\foreach \x in {1,...,#3}
{\pgfmathparse{int(50+\x)}
\edef\n{\pgfmathresult}
\node[mynode,] at (#2*\x,#4+4*#5) {\n};
}
\foreach \x in {1,...,12}
{\pgfmathparse{int(63+\x)}
\edef\n{\pgfmathresult}
\node[mynode,] at (0.5*#2+#2*\x,#4+5*#5) {\n};
}
\end{tikzpicture}
}
\DrawTerminalBlock{4}{.108}{13}{0.1}{0.1}
\end{document}

-
Is it always 75 pins? –  percusse Oct 6 '12 at 20:20
Or always 6 rows? –  Tom Bombadil Oct 6 '12 at 21:11

## 1 Answer

Here's a solution for "always 6 rows". As it's a tedious task finding the right value for #2, I calculate it automatically, therefore the command now has 4 parameters. All you need for the positions is a little div, mod and "ifthenelse" (? :).

## Code

\documentclass{scrartcl}
\usepackage{tikz}
\begin{document}

\parindent0mm

\newcommand{\DrawTerminalBlock}[4]{
\begin{tikzpicture}[scale=#1, thick,node distance=#1in,
mynode/.style={circle, draw, very thin, minimum size=3.5mm, text centered,font=\tiny, inner sep=0.5pt},
]
\coordinate (O) at (0,0) ;
\coordinate (A) at (1.495,0) ;
\coordinate (B) at (1.495, 0.684) ;
\coordinate (C) at (1.309,.870) ;
\coordinate (D) at (0.208,0.870) ;
\coordinate (E) at (0,0.684) ;
\draw (O) --(A) --(B)--( C)-- (D) --(E) --(O)--cycle; %Draw outline
% #1 Scale
% (Horizontal spacing between cavities)
\pgfmathsetmacro{\hsbc}{1.495/(#2+1)}
% #2 Number of horizontal cavities long rows (odd number of cavities)
% #3 Vertical distance to lower (bottom) row
% #4 Vertical spacing between rows

\pgfmathtruncatemacro{\maxval}{6*#2-3}
\foreach \x in {1,...,\maxval}
{   \pgfmathtruncatemacro{\rownum}{2*div(\x-1,2*#2-1)+div(mod(\x-1,2*#2-1),#2)+1}
\pgfmathtruncatemacro{\colnum}{mod(mod(\x-1,2*#2-1),#2)+1}
\pgfmathtruncatemacro{\rowindent}{mod(\rownum,2)==0 ? 1 : 0}
\node[mynode] at ({\hsbc*(\colnum+0.5*\rowindent)},{#3+(\rownum-1)*#4}) {\x};
}

\end{tikzpicture}
}

\DrawTerminalBlock{4}{13}{0.1}{0.1}
\DrawTerminalBlock{4}{5}{0.1}{0.1}\\
\DrawTerminalBlock{8}{19}{0.1}{0.1}

\end{document}


## Output

Edit 1: The number of rows is now choosable, and the vertical positions are computed automatically, reducing the parameters to three:

## Code

\documentclass{scrartcl}
\usepackage{tikz}
\begin{document}

\parindent0mm

\newcommand{\DrawTerminalBlock}[3]{% #1 Scale, #2 Number of horizontal cavities, #3 Number of rows
\begin{tikzpicture}[scale=#1, thick,node distance=#1in, mynode/.style={circle, draw, very thin, minimum size=3.5mm, text centered,font=\tiny, inner sep=0.5pt}]

\coordinate (O) at (0,0) ;
\coordinate (A) at (1.495,0) ;
\coordinate (B) at (1.495, 0.684) ;
\coordinate (C) at (1.309,.870) ;
\coordinate (D) at (0.208,0.870) ;
\coordinate (E) at (0,0.684) ;
\draw (O) --(A) --(B)--( C)-- (D) --(E) --(O)--cycle; %Draw outline

\pgfmathsetmacro{\hsbc}{1.495/(#2+1)}% (Horizontal spacing between cavities)
\pgfmathsetmacro{\vsbr}{0.684/(#3+1)}% (Vertical spacing between rows)
\pgfmathtruncatemacro{\maxval}{(#3*#2)-div(#3,2)}

\foreach \x in {1,...,\maxval}
{   \pgfmathtruncatemacro{\rownum}{2*div(\x-1,2*#2-1)+div(mod(\x-1,2*#2-1),#2)+1}
\pgfmathtruncatemacro{\colnum}{mod(mod(\x-1,2*#2-1),#2)+1}
\pgfmathtruncatemacro{\rowindent}{mod(\rownum,2)==0 ? 1 : 0}
\node[mynode] at ({\hsbc*(\colnum+0.5*\rowindent)},{\rownum*\vsbr}) {\x};
}

\end{tikzpicture}
}

\DrawTerminalBlock{4}{13}{6}
\DrawTerminalBlock{4}{5}{4}\\
\DrawTerminalBlock{8}{17}{13}

\end{document}


## Output

-
@percusse The number of rows varies, as well as the number of cavities per row. There are also special cases where the cavities of one row are of different sizes and at a special spacing locally, but I had in mind to handle these special cases manually. Tom, thanks, your solution is very elegant and educational as well... I have just modified one line into \pgfmathtruncatemacro{\maxval}{(#6*#2)-div(#6,2)} adding a #6 parameter for the number of rows. –  Yves Oct 7 '12 at 7:48