2

I need to draw the plans of a house and make them fit on a page. I would really like to have one set of dimensions/coordinates both in the real life and in my TeX file (I tried in the past to have some dirty scalings, i.e. one dimension in the TeX file others in the real life, but that's not ok).

Is there a way to overcome this error? Thank you! (Please remark the 50m by 50m both in drawing and in the grid)

[Loading MPS to PDF converter (version 2006.09.02).]
)
! Dimension too large.
<to be read again> 
                   \relax 
l.28   \end{scaletikzpicturetowidth}

A MWE (Miktex 2.9.4248 x64; pdfTeX, Version 3.1415926-2.5-1.40.14):

\documentclass[fleqn]{article}
\usepackage{tikz}
\usepackage{pdflscape}
\usepackage{environ}%%%%%%%%%%%%%%%%%%%%%%%%%%

\makeatletter%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newsavebox{\measure@tikzpicture}%%%%%%%%%%%%% \NewEnviron{scaletikzpicturetowidth}[1]{% \def\tikz@width{#1}% \def\tikzscale{1}\begin{lrbox}{\measure@tikzpicture}% \BODY \end{lrbox}% \pgfmathparse{#1/\wd\measure@tikzpicture}% \edef\tikzscale{\pgfmathresult}% \BODY } \makeatother

\begin{document} \begin{center} \begin{scaletikzpicturetowidth}{\textwidth} \begin{tikzpicture}[scale=\tikzscale] \draw [step=10cm, lightgray, very thin] (0,0) grid (50000mm,50000mm); \draw [draw=black, thin] (0.0mm, 0.0mm) rectangle ++(50000mm,50000mm) node[pos=.5] {some labels}; \end{tikzpicture} \end{scaletikzpicturetowidth} \end{center} \end{document}

radui
  • 187

1 Answers1

3
  • Use dimensionless coordinates.
  • Specify the unit length by adding e.g. the option [x=0.005pt,y=0.005pt] to your tikzpicture.

enter image description here

\documentclass{article}
\usepackage{tikz}
\usepackage{lipsum}
\begin{document}
\lipsum[1]
\begin{center}
  \begin{tikzpicture}[x=0.005pt,y=0.005pt]
    \draw [step=100, lightgray, very thin] (0,0) grid  (50000,50000);
    \draw [draw=black, thin] (0.0, 0.0) rectangle ++(50000,50000) node[pos=.5] {some labels};
  \end{tikzpicture}
\end{center}
\lipsum[2]
\end{document}

Auto-scaling the picture to a given width: The environment scaletikzpicturetowidth of the original posting (based on an answer by Philippe Goudet, which in turn is based on a solution by Ulrike Fischer on comp.text.tex) can be adapted to this approach. Add the following lines to the preamble:

\usepackage{environ}
\newsavebox{\measuretikzpicture}
\NewEnviron{scaletikzpicturetowidth}[1]{%
  \def\tikzscale{0.05}% choose small enough to avoid overflows, but large enough to minimize rounding errors
  \savebox{\measuretikzpicture}{\BODY}%
  \pgfmathparse{#1/\wd\measuretikzpicture*\tikzscale}%
  \edef\tikzscale{\pgfmathresult}%
  \BODY
}

In theory, the magic number 0.05 in this definition could be any number, e.g. 1 as in the original posting. In practice, however, numbers in TeX are limited to a small range, so \tikzscale has to be small enough such that no overflows occur (like described in the original posting), but also large enough such that the rounding errors remain negligible. You will notice overflows by TeX giving an error message, while bad rounding errors will result in inadequate scaling.

enter image description here

\documentclass{article}
\usepackage{tikz}
\usepackage{environ}
\newsavebox{\measuretikzpicture}
\NewEnviron{scaletikzpicturetowidth}[1]{%
  \def\tikzscale{0.05}% choose small enough to avoid overflows, but large enough to minimize rounding errors
  \savebox{\measuretikzpicture}{\BODY}%
  \pgfmathparse{#1/\wd\measuretikzpicture*\tikzscale}%
  \edef\tikzscale{\pgfmathresult}%
  \BODY
}
\usepackage{lipsum}
\begin{document}
\lipsum[1]
\begin{center}
  \begin{scaletikzpicturetowidth}{\textwidth}%
    \begin{tikzpicture}[x=\tikzscale pt,y=\tikzscale pt]
      \draw [step=100, lightgray, very thin] (0,0) grid  (50000,20000);
      \draw [draw=black, thin] (0.0, 0.0) rectangle ++(50000,20000) node[pos=.5] {some labels};
    \end{tikzpicture}%
  \end{scaletikzpicturetowidth}
\end{center}
Same picture, but smaller by a factor of 10 (50000 replaced by 5000), again scaled to the text width.
\begin{center}
  \begin{scaletikzpicturetowidth}{\textwidth}%
    \begin{tikzpicture}[x=\tikzscale pt,y=\tikzscale pt]
      \draw [step=100, lightgray, very thin] (0,0) grid  (5000,2000);
      \draw [draw=black,thin] (0.0, 0.0) rectangle ++(5000,2000) node[pos=.5] {some labels};
    \end{tikzpicture}%
  \end{scaletikzpicturetowidth}
\end{center}
\lipsum[2]
\end{document}
gernot
  • 49,614
  • Thank you gernot! Removing the units might make code more readable, but I don't really enjoy playing with the scales (i.e. x=0.005pt, y=0.005pts) for every new drawing I'm doing ... it's there a way of automatically scaling the figure using your "implementation" (i.e. without specifying the units)? – radui Aug 07 '21 at 15:43
  • (by "new drawing" I mean I might need to rethink something/redraw it/update it and replace it in the original drawing. If the thing I'm redrawing is not so big I might not see something ... I totally dislike playing with the units) – radui Aug 07 '21 at 15:53
  • @radui I have added an auto-scaling solution to my answer. There may be one problem, though: Changing the unit lengths x and y does not affect labels. As you will notice in the example, some labels appears in normal size. The grey background is the result of your 10cm-grid. – gernot Aug 07 '21 at 16:03
  • Thank you Germot once again! (1) the labels size and the grid are not a problem for the moment; (2) I'm not a very profound latex programmer but I think, you somehow hard-code some things in your new environment (I'm referring mainly to the following lines \def\tikzscale{0.001}% and \pgfmathparse{#1/\wd\measuretikzpicture*0.001}%). This will be visible when I'm going to redraw some parts of the original drawing in a separate figure (e.g. one room, which will be much smaller than the entire house); the part drawn separately will not resize to fill the page & will remain (maybe) too small. – radui Aug 07 '21 at 16:18
  • @radui Well, try it. Your small room should also fill the whole page. What the command does: draw the picture small enough such that no overflow occurs, measure the width, compute the rescaling factor, and then redraw the picture again such it fills the whole page. In your original code, there were also hard-coded numbers like 1, but which lead to an overflow. The constraint for choosing the number is just that the drawing can be typeset without over- and underflows. So, if you decide to draw a world map with lengths in mm, 0.001 will be too big, so you might have to shrink it further. – gernot Aug 07 '21 at 16:23
  • Thank you Gernot! I'd just uploaded a picture here. It shows on the left page, the big square 50mx50m, split in 4 pieces and on the right page, one of the pieces drawn isolated; on both pages there is some text to show the textwidth. (1) what should be done/changed in your code so that the width of the image is the same as the textwidth? (2) what should be changed in your code so that the isolated rectangle (from the right page) is the same size as the one from the left page? Thank you, for all your patience, efforts and time! – radui Aug 07 '21 at 16:47
  • @radui I corrected the solution, and added an explanation. What you observed (inadequate scaling) was the result of rounding errors, because the numbers got too small for TeX. So the magic number you complained about has to be chosen wisely to avoid overflows as well as underflows/rounding errors. – gernot Aug 07 '21 at 18:12
  • I believe these answer my initial questions/request. I would like to thank you @gernot for all your efforts. I only hope not to have weird numbers and make the code fail/break again. Thank you:) R – radui Aug 07 '21 at 18:53