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}

enter image description here

Tags:

Tikz Pgf