2

I am working on a three-column dotted grid template for note-taking/writing cheatsheets if TeX'd ones are not allowed. I have the following code:

\documentclass{article}

\usepackage[margin=1.5cm,landscape,a4paper]{geometry}
\usepackage{tikz}
\usetikzlibrary{patterns,patterns.meta}

\definecolor{dotcolor}{RGB}{204,204,198}

\setlength\parindent{0pt}

\usepackage{layouts,blindtext}

\def\columnwid{0.314606742}

\begin{document}
\thispagestyle{empty}


\begin{minipage}[b]{\columnwid\textwidth}
\begin{tikzpicture}[x=1cm, y=1cm]
 \draw[pattern={Dots[distance=5mm,radius=0.4mm,xshift=0.21cm,yshift=0.29cm]},pattern color=dotcolor,draw=dotcolor!70] (0,0) rectangle +(\textwidth,0.999\textheight);
\end{tikzpicture}
\end{minipage}\hfill
\begin{minipage}[b]{\columnwid\textwidth}
\begin{tikzpicture}[x=1cm, y=1cm]
 \draw[pattern={Dots[distance=5mm,radius=0.4mm,xshift=-0.15cm,yshift=0.29cm]},pattern color=dotcolor,draw=dotcolor!70] (0,0) rectangle +(\textwidth,0.999\textheight);
\end{tikzpicture}
\end{minipage}\hfill
\begin{minipage}[b]{\columnwid\textwidth}
\begin{tikzpicture}[x=1cm, y=1cm]
 \draw[pattern={Dots[distance=5mm,radius=0.4mm,yshift=0.29cm]},pattern color=dotcolor,draw=dotcolor!70] (0,0) rectangle +(\textwidth,0.999\textheight);
\end{tikzpicture}
\end{minipage}

\end{document}

which produces:

Three-column template

The result is exactly what I wanted. However, I had to calculate the parameters (such as \columnwid (width of one column after outer margin (1.5 cm) and inner margin (0.75 cm), or the shift values), etc. by hand, which is less ideal if I want a different layout (such as portrait two-column). This can be automated by doing the calculations within LaTeX (such as Calculations on variables using LaTeX)

The topic of this question, however, is the grid pattern. If you remove the x-shift and y-shift parameters, the dots appear arranged differently in each column (i.e. not all of them "start" where the column border is drawn), which is unexpected, because the tikzpicture is drawn in each minipage (for columns).

How can I adjust this, so as to have an evenly-spaced pattern?

4
  • Why did you have to calculate \columnwid by hand? The only thing you control by it is the width of each minipage as well as the space between the minipages. The pattern is fixed to the page which makes it annoying to deal with. You could draw a custom dot pattern just by doing \draw[dash pattern=on 0pt off <distance>, line width=<diameter>, line cap=round, ystep=0, xstep=<distance>] (0,0) grid (\textwidth, \textheight);. Commented Jan 27, 2023 at 14:21
  • What are the rules for the dots? It might be doable by remembering the picture (remember picture) and figuring the shift parameters from the relative position on the page, though I would just draw the dots manually (as per grid). Commented Jan 27, 2023 at 14:24
  • And lastly, do you actually need three minipages or could you just use one TikZpicture for everything? Commented Jan 27, 2023 at 15:39
  • @Qrrbrbirlbel I calculated \columnwid by hand because if I used 0.3\textwidth it would achieve a similar result, but I would like to have the inner margins (i.e. those seperating the columns) to be a specific width. \columnwid can be calculated by substracting the margins (*2 for both inner and outer margins) and dividing by 3 (for three columns). I didn't know that the pattern is fixed to the page. The rules for the dots can be found in the parameters (i.e. 5 mm spacing, 0.4 mm thickness). I used minipages to achieve the page layout, I'm not sure I can combine it into one Tikz.
    – Max R
    Commented Jan 27, 2023 at 16:14

2 Answers 2

6

The TikZ manual explains about patterns:

There are a number of pitfalls and restrictions when using patterns. […]

[T]he phase of patterns is not well-defined, that is, it is not clear where the origin of the “first” tile is. To be more precise, PostScript and PDF on the one hand and SVG on the other hand define the origin differently. PostScript and PDF define a fixed origin that is independent of where the path lies. This has the highly desirable effect that if you use the same pattern to fill multiple paths, the outcome is the same as if you had filled a single path consisting of the union of all these paths.

In your case, this is not highly desirable.

If we knew where the actual origin is we could calculate the needed shifting but I believe it to be easier to draw with the main TikZ methodes not as a pattern (i.e. something that is handled by the “underlying grapih languages”) even though it might be slower.


In the following code, the dots are drawn with a special dash pattern that has on segment of zero length but a round line cap. Thus, these dots are not drawn as a circle (shape or path operation) but part of a line. Their size are controlled by the line width.

Rules:

The only flexible distances are

  • the margin between the dotted columns,
  • the width of the dotted columns and
  • the vertical margin between the dots and the top and bottom of the column.

Variables:

  • columns: number of dotted columns

  • dot distance: distance between the dots' centers

  • dot diameter: the diameter of the dots (not the radius)

  • margin: the space between the outer dots' centers and the rectangles.

    For the horizontal dimension this is a fixed length, for the vertical dimension it is considered to be a minimum.

  • minimal column sep: the minimal horizontal space between the columns

Styles:

  • @dots: internal style that sets the appropriate grid and line settings

  • rectangle: the style of the rectangle

  • dots: the style of the dots

  • diagram: somewhat internal style that instructs TikZ how to place the whole picture on the page.

    The trims are needed so that the line width of the rectangles is ignored (they line up exactly on the border of the text area. The baseline helps to not have empty pages.


The formulas are probably not optimal, I've only figured out a bit too late that I could use the mod function.

This could still be multiple TikZ pictures where the space between them is controlled by TeX but this is the first solution I've came up with.

Code

\documentclass{article}
\usepackage[margin=1.5cm,landscape,a4paper,showframe]{geometry}
\usepackage{tikz}
\definecolor{dotcolor}{RGB}{204,204,198}
\setlength\parindent{0pt}
% \usepackage{layouts,blindtext}
\tikzset{
  maxgrid/dot distance/.initial=+5mm,
  maxgrid/dot diameter/.initial=+.8mm,
  maxgrid/margin/.initial=+3mm,
  maxgrid/minimal column sep/.initial=+10mm,
  maxgrid/columns/.initial=3,
  maxgrid/@dots/.style={
    xstep=\pgfkeysvalueof{/tikz/maxgrid/dot distance}, ystep=+0pt,
    line width=\pgfkeysvalueof{/tikz/maxgrid/dot diameter}, line cap=round,
    dash pattern=on +0pt off \pgfkeysvalueof{/tikz/maxgrid/dot distance}},
  maxgrid/rectangle/.style={draw=dotcolor!70},
  maxgrid/dots/.style={draw=dotcolor},
  maxgrid/diagram/.style={trim left=+0pt,trim right=+\linewidth,baseline=+1em}}
\newcommand*\tikzmaxgrid[1][]{%
\begin{tikzpicture}[maxgrid/diagram,maxgrid/.cd,#1]
\pgfmathtruncatemacro\tmgDotsPerColumn{
  ((\linewidth-(\pgfkeysvalueof{/tikz/maxgrid/columns}-1)
              *(\pgfkeysvalueof{/tikz/maxgrid/minimal column sep})
             )/(\pgfkeysvalueof{/tikz/maxgrid/columns})
            -2*(\pgfkeysvalueof{/tikz/maxgrid/margin})
             )/(\pgfkeysvalueof{/tikz/maxgrid/dot distance})}
\pgfmathsetlengthmacro\tmgColumnWidth{
  \tmgDotsPerColumn*(\pgfkeysvalueof{/tikz/maxgrid/dot distance})
                 +2*(\pgfkeysvalueof{/tikz/maxgrid/margin})}
\pgfmathsetlengthmacro\tmgColumnWidthExtra{
  (\linewidth-(\pgfkeysvalueof{/tikz/maxgrid/columns})*\tmgColumnWidth)
             /(\pgfkeysvalueof{/tikz/maxgrid/columns}-1)}
\pgfmathsetlengthmacro\tmgYMargin{
  .5*mod(\textheight,\pgfkeysvalueof{/tikz/maxgrid/dot distance})}
\pgfmathsetlengthmacro\tmgYMargin{
  \tmgYMargin < \pgfkeysvalueof{/tikz/maxgrid/margin} ?
    \tmgYMargin+.5*(\pgfkeysvalueof{/tikz/maxgrid/dot distance}) : \tmgYMargin}
\foreach[parse=true, count=\tmgColumnZero from 0] \tmgColumn in {
  1,...,\pgfkeysvalueof{/tikz/maxgrid/columns}}{
  \draw[maxgrid/rectangle,
        xshift=\tmgColumnZero*(\tmgColumnWidth+\tmgColumnWidthExtra]
    (0,0) rectangle ++ (\tmgColumnWidth,\textheight);
  \draw[maxgrid/@dots, maxgrid/dots,
        xshift=\tmgColumnZero*(\tmgColumnWidth+\tmgColumnWidthExtra,
        shift={({\pgfkeysvalueof{/tikz/maxgrid/margin}},\tmgYMargin)}]
    (+0pt,+0pt) grid ++(
      {\tmgColumnWidth-2*(\pgfkeysvalueof{/tikz/maxgrid/margin})},
      {\textheight-2*\tmgYMargin});}
\end{tikzpicture}}
\begin{document}
\tikzmaxgrid[columns=2]

\tikzmaxgrid

\tikzmaxgrid[columns=4, minimal column sep=5mm]
\end{document}

Output

Somewhere between pages 2 and 3:
enter image description here

1
  • If the space between the columns is supposed to be fixed and the margins should just be a threshold, adjustments need to be made. Commented Jan 27, 2023 at 18:05
3

This is a simple code (tikz only) where there is an integer number of points in each column (\nropoints). Also, the space between columns has a width equal to an integer number of points (\intercolumnspoints).

The space between points (\dotdistance) is calculated to fill the entire width of the text using

\textwidth = 3*\nropoints\dotdistance + 2*\intercolumnspoints\dotdistance

That way the xshift is no longer needed.

a

Only two parameters to set:

Number of points within each column (integer)

"Width" of column spacing measured in number of points (integer)

\documentclass{article}

\usepackage[margin=1.5cm,landscape,a4paper, showframe]{geometry} % changed to show the margins <<<
\usepackage{tikz}
\usetikzlibrary{patterns,patterns.meta}

\definecolor{dotcolor}{RGB}{204,204,198}

\setlength\parindent{0pt}

\usepackage{layouts,blindtext}

%******************************************** added 
\usepackage{fp}
\FPset\nropoints{17}% choose the number of inner points per column (integer) <<<<<<<<<<<<<<<<
\FPset\intercolumnspoints{2} % choose the "width" of column separation (integer) <<<<<<<<<<<<<<<

\FPeval\totalpoints{3*\nropoints + 2*\intercolumnspoints}
\FPeval\factorx{ 1 /\totalpoints}

\newlength{\dotdistance}
\setlength{\dotdistance}{\factorx\textwidth}% to fill the text width

\newlength{\colW}
\setlength{\colW}{\nropoints\dotdistance}
\setlength{\columnsep}{\intercolumnspoints\dotdistance} % 
%********************************************

\begin{document}
\thispagestyle{empty}   
    
\begin{tikzpicture}     

\pgfmathsetmacro\d{\dotdistance}    
    
\draw[pattern={Dots[distance=\d,radius=0.4mm]},pattern color=dotcolor](0,0) rectangle +(\colW,0.999\textheight);

\draw[pattern={Dots[distance=\d,radius=0.4mm]},pattern color=dotcolor](\colW+\columnsep,0) rectangle +(\colW,0.999\textheight);

\draw[pattern={Dots[distance=\d,radius=0.4mm,]},pattern color=dotcolor](2*\colW+2*\columnsep,0) rectangle +(\colW,0.999\textheight);    

\end{tikzpicture}
\end{document}

With

\FPset\nropoints{20}%(integer)
\FPset\intercolumnspoints{1} 

b

the columns separation is 12.25pt

You must log in to answer this question.

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