9

why can not some lines(red ones) be drawn?

enter image description here

the following is my codes

\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);
 \foreach \x in {-0.8,1,...,10.9}
 \foreach \y in {0.2,2,...,7.4}
  \draw  (\x ,\y)  --(\x+0.9 ,\y);
\foreach \l in {0.6,2.4,...,9.6}
   \foreach \m in {-0.2,1.6,...,8.8}
    \draw (\l,\m) -- (\l,\m+0.9);
     \foreach \x in {0.1,1.9,...,9.1}
 \foreach \y in {1.1,2.9,...,6.5}
  \draw  (\x ,\y)  --(\x+0.9 ,\y);
\foreach \l in {1.5,3.3,...,10.5}
   \foreach \m in {0.7,2.5,...,6.1}
    \draw(\l,\m) -- (\l,\m+0.9);
\end{tikzpicture}
\end{document} 

Another question: are there any simpler\better methods drawing these lines?

12

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);
  • Great, those four lines appear. Thanks a lot. The other question, do you have better method simplifying the codes? – dozer Feb 23 '17 at 12:20
8

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

  • Another very good method! Thank you very much! – dozer Feb 23 '17 at 15:05
8

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.

  • Thank you very much! excellent computing power! but i can not understand your codes, where can I find the detained explanation of your codes, e.g., your expression. – dozer Feb 23 '17 at 14:19
  • @dozer I can add some more explanation later tonight. The key thing is (-1)^(\x+\y) I suppose. Consider \x and \y as indices of a matrix, one giving the row number, the other the column number. If \x+\y is an odd number, (-1)^(\x+\y) = -1, if \x+\y is an even number then (-1)^(\x+\y) = 1. This makes the pattern -1 1 -1 1 .. along both rows and columns. The ifthenelse and \ifnum is for making the code do different things depending on the whether we have 1 or -1. – Torbjørn T. Feb 23 '17 at 14:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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