why won't \foreach work correctly?
You should take into account rounding errors. So enlarge the last value a bit, e.g. to 10.51.
Beside this I would use integers for the steps and then calculate the values. E.g. for your last one:
\foreach \l in {1,2,...,6} %
\foreach \m in {0,1,...,3} %
\draw(1.5+1.8*\l,0.7+1.8*\m) -- (1.5+1.8*\l,0.7+1.8*\m+0.9);
A different approach to drawing such patterns, using just two nested loops.
\documentclass[tikz,border=5pt]{standalone}
\begin{document}
\begin{tikzpicture}
\clip (0,0) rectangle (10.8,7.2);
\draw (0,0) rectangle (10.8,7.2);
\newcommand\dx{0.9} % horizontal distance between the line centers
\newcommand\dy{0.9} % vertical distance between the line centers
\pgfmathsetmacro\lx{\dx/2} % half length of horizontal line
\pgfmathsetmacro\ly{\dy/2} % half length of vertical line
\foreach \x in {-2,...,15} {
\foreach \y in {-1,...,9} {
\pgfmathsetmacro\ifhoriz{ifthenelse((-1)^(\x+\y)<0,0,1)}
\ifnum \ifhoriz=0
\draw (\x*\dx-\lx,\y*\dy) -- (\x*\dx+\lx,\y*\dy);
\else
\draw (\x*\dx,\y*\dy-\ly) -- (\x*\dx,\y*\dy+\ly);
\fi
}}
\end{tikzpicture}
\end{document}
Or if the spacing and line length is always the same for x and y, you can make do with a single \draw
:
\documentclass[tikz,border=5pt]{standalone}
\begin{document}
\begin{tikzpicture}
\clip (0,0) rectangle (10.8,7.2);
\draw (0,0) rectangle (10.8,7.2);
\newcommand\dx{0.9} % distance between center of lines in pattern
\pgfmathsetmacro\lx{\dx/2} % half length of lines in pattern
\foreach \x in {-2,...,15} {
\foreach \y in {-1,...,9} {
\draw [rotate around={ifthenelse((-1)^(\x+\y)<0,0,90):(\x*\dx,\y*\dx)}]
(\x*\dx-\lx,\y*\dx) -- (\x*\dx+\lx,\y*\dx);
}}
\end{tikzpicture}
\end{document}
In both cases, instead of using explicit x and y values in the loop, I use integers as Ulrike does in her answer. To decide whether to draw a horizontal or vertical line, I calculate (-1)^(\x+\y)
, where \x
and \y
are the integers. If you write up a matrix of those values, it will look like
y\x | 1 2 3 4 5
---------------------
1 | 1 -1 1 -1 1
2 | -1 1 -1 1 -1
3 | 1 -1 1 -1 1
4 | -1 1 -1 1 -1
So every other 1 and -1, along both axes.
In the first case, I use ifthenelse((-1)^(\x+\y)<0,0,1)
to set the macro \ifhoriz
to either 0 or 1, and then I use \ifnum
to draw a horizontal line if \ifhoriz
is 0, and a vertical line if it is 1.
In the second case I draw a horizontal line, but I use a similar ifthenelse
statement to rotate the line either 0 or 90 degrees.
Instead of a \foreach
you could use a new defined pattern
\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{positioning, patterns}
\tikzset{
hatch thickness/.store in=\hatchthickness,
hatch thickness=1pt
}
\makeatletter
\pgfdeclarepatternformonly[\hatchthickness]{myhatch}
{\pgfpointorigin}{\pgfpoint{18mm}{18mm}}
{\pgfpoint{18mm}{18mm}}
{
\pgfsetcolor{\tikz@pattern@color}
\pgfsetlinewidth{\hatchthickness}
\pgfpathmoveto{\pgfpoint{0mm}{4.5mm}}
\pgfpathlineto{\pgfpoint{9mm}{4.5mm}}
\pgfpathmoveto{\pgfpoint{9mm}{13.5mm}}
\pgfpathlineto{\pgfpoint{18mm}{13.5mm}}
\pgfpathmoveto{\pgfpoint{4.5mm}{9mm}}
\pgfpathlineto{\pgfpoint{4.5mm}{18mm}}
\pgfpathmoveto{\pgfpoint{13.5mm}{0mm}}
\pgfpathlineto{\pgfpoint{13.5mm}{9mm}}
\pgfusepath{stroke}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\filldraw[pattern=myhatch, pattern color=red] (0,0) rectangle (10.8,7.2);
\end{tikzpicture}
\end{document}