2

I drew a ruler using the MWE below then I realized that It draws each medium (5 mm step) vertical line over the small ones (1 mm step) and each large (numbered) vertical bar over both medium and small ones. So, my question is: how to use conditionals to prevent overlapping?

\documentclass[tikz, border=10pt]{standalone}


\begin{document}

    \begin{tikzpicture}[{x=(1mm,0)},{y=(0,1mm)}]
        \tiny
        \draw
            (0,0)
            rectangle(150,-15)
        ;

        \foreach \x in {5, 6, ..., 145}{
            \draw (\x, 0)--(\x, -2);
        }
        \foreach \y in {5, 10, ..., 145}{
            \draw (\y, 0)--(\y, -4);
        }
        \foreach \z in {5, 15, ..., 145}{
            \pgfmathsetmacro{\d}{(\z - 5)/10}
            \draw (\z, 0)--(\z, -6) node[below]{\pgfmathprintnumber[fixed,precision=0]{\d}};
        }
    \end{tikzpicture}

\end{document}

enter image description here

2
  • You're right, it draws a few ticks too often but this should only be a render issue, another PDF viewer and your printer will output this differently. (But it's a good idea to surpress these anyway.) Commented Sep 24, 2023 at 21:01
  • I just noticed that the 5s and 10s can be totally distinctive loops: with my setup one for 0, 10, ..., 140 and the other for 5, 15, ..., 135. The smallest tick might be solved by two nested loops: \foreach \x in {0, ..., 13} \foreach \xx in {1, 2, 3, 4, 6, 7, 8, 9} and then use 10*\x + \xx as the x value. Commented Sep 24, 2023 at 21:50

2 Answers 2

2

Maybe this is an easier approach:

We use one loop to go through all ticks and check for each one whether it is divisible by 10 and 5 and choose the appropriate length.

The function mod(<x>, <n>) returns the remainder of <x>/<n> but 0 will be interpreted by ifthenelse as false where as all other results will be interpreted as true.

Of course, you can put the whole function for \ticklength directly into the path:

\draw (\x, 0) -- +(down:{ifthenelse(mod(\x, 10), ifthenelse(mod(\x, 5), 2, 4), 6)};

but if you need it more than once, the evaluate key is a good tool for it.

For the numbers we could use the same loop with another conditional test in various ways but it seems easier to just emply a second loop that iterates directly over the integers. (We could actually write \x0 instead of 10*\x but the latter is syntactical more correct, I guess.)

Code

\documentclass[tikz, border=10pt]{standalone}
\begin{document}
\begin{tikzpicture}[x=1mm, y=1mm]
\tiny
\draw (-5 ,0) rectangle (145, -15);

\foreach[
  evaluate={
    \ticklength=
      ifthenelse(mod(\x, 10),
        ifthenelse(mod(\x, 5), 2, 4), 6);}] \x in {0, ..., 140}
  \draw (\x, 0) -- +(down:\ticklength);
\foreach \x in {0, ..., 14}
  \node[below] at (10*\x, -6) {$\x$};
\end{tikzpicture}
\end{document}
0

(too long for a comment)

Your question is clear, but in my opinion, such the overlappings do not matter. It's not difficult to avoid such the overlappings, but the price we have to pay is the complexity and readibility of codes.

Your ruler figure reminds me one of the first tikzpictures I have drawn. Hope the code is helpful for someone.

enter image description here

\documentclass[tikz,border=3mm]{standalone}
\begin{document}
\begin{tikzpicture}[line cap=round,line join=round,x=1mm,y=1mm]
% a ruler
\fill[gray!20] (0,-2) rectangle (100,0);
\foreach \i in {0,...,100} 
    \draw (\i,0)--+(0,-2);
\foreach \i in {0,...,20} 
    \draw (5*\i,0)--+(0,-4);
\foreach \i in {0,...,10}
    \draw (10*\i,0)--++(0,-6) node[below]{\i};
\draw (0,-12) node[align=left]{cm};
\draw[thick,rounded corners] (-5,-20) rectangle (105,0);

% a pink pencil
\begin{scope}[yshift=4pt]
\fill[red!60] (0,0) rectangle (85,1.5);
\fill[red!40] (0,1.5) rectangle (85,3.5);
\fill[red!20] (0,3.5) rectangle (85,5);
\fill[black!50] (95,2.5) circle(1pt);
\fill[draw=black,left color=white,right color=black!20] (85,0)--(95,2.5)--(85,5);
\draw[black!50,opacity=.5] (0,0) rectangle (85,5);              
\end{scope}
\end{tikzpicture} 
\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .