
Вопрос
Как сделать так, чтобы линии сетки идеально совпадали, чтобы они соответствовали физическим миллиметрам на странице?
Ситуация
У меня есть лист бумаги формата А4. Я хочу нарисовать на нем линии сетки, промаркировав каждый миллиметр (разумеется, размер нумерации предназначен для цифрового использования, реалистично сантиметры будут промаркированы для физической печати).
Критерии
- Подходит для любого размера бумаги (при условии
\step
настройки максимального размера) - Линии соответствуют физическим размерам
- Наложение будет покрывать любые другие изображения tikz (или что-либо еще) независимо от того, где в документе вызывается команда (я могу вызвать команду на любой странице, где мне нужна сетка)
Проблема
- Линии не начинаются в начале координат.
- Сетка не находится выше
tikzpicture
вызываемого элемента внутри документа независимо от того, где\showgrid
он вызывается.
Пример кода
\documentclass{article}
\usepackage{fontspec}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{anyfontsize}
\newcommand{\showgrid}{%
\begin{tikzpicture}[overlay,remember picture,every node/.style={inner sep=0pt,outer sep=0pt}]%
\draw[help lines,xstep=1mm,ystep=1mm,gray!25] (current page.north west) grid (current page.south east);
\draw[help lines,xstep=10mm,ystep=10mm,color=gray] (current page.south west) grid (current page.north east);
\foreach \step in {0,1,...,297} {
\node [anchor=north] at ($ (current page.north west) + (\step mm,0cm) $) {\fontsize{1}{2}\selectfont \step};
\node [anchor=west] at ($ (current page.north west) + (0cm,-\step mm) $) {\fontsize{1}{2}\selectfont \step};
}
\end{tikzpicture}
}%
\begin{document}
\thispagestyle{empty}
\showgrid{}
\begin{tikzpicture}[overlay,remember picture,every node/.style={fill=red,inner sep=0pt,outer sep=0pt}]%
\node [minimum width=2cm,minimum height=2cm] at (current page.center) {};
\end{tikzpicture}%
\end{document}
Выход
ОБНОВЛЕНИЕ: Мое решение
Это гибридное решение, которое использует подход CFR в сочетании с автоматическим определением размера страницы ответа ESDD.
\documentclass[a4paper]{article}
\usepackage{tikz}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc}
\usetikzlibrary{backgrounds}
\usepackage{anyfontsize}
\usepackage{atbegshi}
\newcommand{\showgrid}{%
\AtBeginShipoutNext{\AtBeginShipoutAddToBoxForeground{%
\begin{tikzpicture}
[
overlay,
remember picture,
inner sep=0pt,
outer sep=0pt,
minor line/.style={help lines, draw=black!50, on background layer},
major line/.style={help lines, draw=black},
major number/.style={font=\fontsize{3}{5}\selectfont\bfseries},
minor number/.style={font=\fontsize{1}{2}\selectfont},
]
\pgfmathtruncatemacro\xmaxstep{\paperwidth/1mm}% calculate needed steps in x direction
\pgfmathtruncatemacro\ymaxstep{\paperheight/1mm}% calculate needed steps in y direction
\foreach \step in {0,1,...,\xmaxstep} {
\pgfmathsetmacro\gridlineconfig{ifthenelse(equal(int(mod(\step,10)),0),"major line","minor line")}%
\draw [\gridlineconfig] ($(current page.north west) + (\step mm,0)$) -- ($(current page.south west) + (\step mm,0)$);
}
\foreach \step in {0,1,...,\ymaxstep} {
\pgfmathsetmacro\gridlineconfig{ifthenelse(equal(int(mod(\step,10)),0),"major line","minor line")}%
\pgfmathsetmacro\numberconfig{ifthenelse(equal(int(mod(\step,10)),0),"major number","minor number")}%
\draw [\gridlineconfig] ($(current page.north west) - (0,\step mm)$) -- ($(current page.north east) - (0,\step mm)$);
\node [anchor=north,\numberconfig] at ($ (current page.north west) + (\step mm,0) $) {\step};
\node [anchor=west,\numberconfig] at ($ (current page.north west) - (0,\step mm) $) {\step};
}
\end{tikzpicture}
}%
}%
}
\tikzset{%
myseg/.style={%
red,very thick
}
}
\begin{document}
\null
\showgrid
\begin{tikzpicture}[overlay,remember picture]
\draw [myseg] (current page text area.north west) -- (current page text area.north east) -- (current page text area.south east) -- (current page text area.south west) -- (current page text area.north west);
\draw [myseg] (current page header area.north west) -- (current page header area.north east) -- (current page header area.south east) -- (current page header area.south west) -- (current page header area.north west);
\draw [myseg] (current page footer area.north west) -- (current page footer area.north east) -- (current page footer area.south east) -- (current page footer area.south west) -- (current page footer area.north west);
\draw [myseg] (current page marginpar area.north west) -- (current page marginpar area.north east) -- (current page marginpar area.south east) -- (current page marginpar area.south west) -- (current page marginpar area.north west);
\end{tikzpicture}
\end{document}
Выход
Примечание:При обратном проектировании макетов эту сетку можно напечатать поверх другого PDF-файла, используя опцию масштабирования по полям принтера в большинстве меню печати, поскольку и PDF-файл, и сетка будут масштабироваться в одинаковом соотношении, что означает, что уменьшенные миллиметры будут эквивалентны миллиметрам на подлежащем PDF-файле. Пример рисования на изображениях с использованием этого кода можно найти здесь:https://tex.stackexchange.com/a/269156/13552
решение1
Обратите внимание, что ширина линий может не выглядеть ровной в опубликованных PNGS. Это артефакт комбинации маленького экрана/PDF-просмотрщика, и он не имеет ничего общего с самим PDF. Это влияет только на мои вырезки PNG.
Я думаю, что это решение удовлетворяет различным требованиям:
- Можно адаптировать к другим форматам бумаги, изменив определения
\step
s. - Северо-западный угол листа бумаги находится в начале координат, а линии сетки совпадают с физическими размерами страницы в том смысле, что северо-западные углы как маленького квадрата, так и большого квадрата сетки совпадают с северо-западным углом страницы.
- Сетка накладывается на остальное содержимое страницы, включая
tikzpicture
s, даже если они используютoverlay, remember picture
сами себя. \showgrid
можно указать в любом месте страницы, где требуется сетка, в том числе перед любымиtikzpicture
s, даже если они сами используютoverlay, remember picture
.- Сетка отображается только на запрошенной странице. Для следующей страницы сетка использоваться не будет. (Но было бы легко адаптировать ее так, чтобы она отображалась на каждой странице или где-то еще. См. документацию
atbegshi
.)
Я нарисовал сетку вручную, рисуя горизонтальные и вертикальные линии отдельно. Я использую библиотеку, backgrounds
чтобы гарантировать, что более светлые линии не будут нарисованы поверх более темных (что выглядит довольно странно).
Я использую его atbegshi
для того, чтобы сетка располагалась над всем содержимым страницы.
\documentclass[a4paper]{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{backgrounds}
\usepackage{anyfontsize}
\newcommand{\showgrid}{%
\AtBeginShipoutNext{\AtBeginShipoutAddToBoxForeground{%
\begin{tikzpicture}
[
overlay,
remember picture,
inner sep=0pt,
outer sep=0pt,
minor line/.style={help lines, draw=gray!25, on background layer},
major line/.style={help lines, draw=gray},
]
\foreach \step in {0,...,210} {
\pgfmathsetmacro\gridlineconfig{ifthenelse(equal(int(mod(\step,10)),0),"major line","minor line")}%
\draw [\gridlineconfig] ($(current page.north west) + (\step mm,0)$) -- ($(current page.south west) + (\step mm,0)$);
}
\foreach \step in {0,...,297} {
\pgfmathsetmacro\gridlineconfig{ifthenelse(equal(int(mod(\step,10)),0),"major line","minor line")}%
\draw [\gridlineconfig] ($(current page.north west) - (0,\step mm)$) -- ($(current page.north east) - (0,\step mm)$);
\node [anchor=north] at ($ (current page.north west) + (\step mm,0) $) {\fontsize{1}{2}\selectfont \step};
\node [anchor=west] at ($ (current page.north west) - (0,\step mm) $) {\fontsize{1}{2}\selectfont \step};
}
\end{tikzpicture}
}%
}%
}
\usepackage{atbegshi}
\begin{document}
\thispagestyle{empty}
\showgrid
\begin{tikzpicture}[overlay,remember picture,every node/.style={fill=red,inner sep=0pt,outer sep=0pt}]%
\node [minimum width=2cm,minimum height=2cm] at (current page.center) {};
\end{tikzpicture}
\end{document}
решение2
Команда \AddToShipoutPictureFG*
, определенная пакетом, eso-pic
устанавливает его содержимое поверх текущей страницы. Кроме того, можно рассчитать необходимое количество этикеток по осям x и y в зависимости от размера бумаги.
\documentclass[a5paper]{article}
%\usepackage{fontspec} % commented to speed up compilation
\usepackage{blindtext}% dummy text
\usepackage{tikz}
\usepackage{anyfontsize}
\usepackage{eso-pic}
\newcommand{\showgrid}{%
\AddToShipoutPictureFG*{%
\begin{tikzpicture}[overlay,remember picture,
thin,nodes={font=\fontsize{1}{2}\selectfont},
yshift=\paperheight% origin is in the upper left corner
]
\draw[gray!25,step=1mm](current page.south west)grid(current page.north east);
\draw[blue!30!gray,step=10mm](current page.south west) grid(current page.north east);
\pgfmathtruncatemacro\xmaxstep{\paperwidth/1mm}% calculate needed steps in x direction
\pgfmathtruncatemacro\ymaxstep{\paperheight/1mm}% calculate needed steps in y direction
\foreach \step in {0,1,...,\xmaxstep}
\node [anchor=north] at ([xshift=\step mm]current page.north west) {\step};
\foreach \step in {0,1,...,\ymaxstep}
\node [anchor=west] at ([yshift=-\step mm]current page.north west) {\step};
% \node[fill=red]at(0,0){};% to show the origin
\end{tikzpicture}%
}%
}
\begin{document}
\blindtext[2]
\showgrid
\tikz[overlay,remember picture]\node[minimum size=2cm,fill=red] at (current page.center) {};
\blinddocument
\showgrid
\blinddocument
\end{document}
С помощью пакета scrlayer
вы можете определить сетку как новый стиль страницы.
\documentclass[a5paper]{article}
%\usepackage{fontspec} % commented to speed up compilation
\usepackage{blindtext}% dummy text
\usepackage{tikz}
\usepackage{anyfontsize}
\usepackage{scrlayer}
\DeclareNewLayer[foreground,page,
contents={%
\begin{tikzpicture}[thin,nodes={font=\fontsize{1}{2}\selectfont}]
\useasboundingbox(0,0)rectangle(\layerwidth,-\layerheight);
\draw[gray!25,step=1mm](0,0)grid(\layerwidth,-\layerheight);
\draw[orange!30!gray,step=10mm](0,0)grid(\layerwidth,-\layerheight);
\pgfmathtruncatemacro\xmaxstep{\layerwidth/1mm}% calculate needed steps in x direction
\pgfmathtruncatemacro\ymaxstep{\layerheight/1mm}% calculate needed steps in y direction
\foreach \step in {0,1,...,\xmaxstep}
\node [anchor=north] at (\step mm,0) {\step};
\foreach \step in {0,1,...,\ymaxstep}
\node [anchor=west] at (0,-\step mm){\step};
\end{tikzpicture}%
}
]{grid.fg}
\DeclareNewPageStyleByLayers{grid}{grid.fg}
\pagestyle{headings}
\begin{document}
\blindtext[2]
\thispagestyle{grid}
\tikz[overlay,remember picture]\node[minimum size=2cm,fill=red] at (current page.center) {};
\blinddocument
\thispagestyle{grid}
\blinddocument
\end{document}
решение3
Частичное решение
В приведенном ниже коде есть несколько незначительных проблем.
начало координат сетки находится в левом нижнем углу страницы (автор хочет верхний левый угол)
использование
\AddToShipoutPicture
делает начало координат равным 1. но также создает сетку под содержимым страницы. Убирая его, сетка уходит под, но начало координат становится сумасшедшим.
С\AddToShipoutPicture
Без\AddToShipoutPicture
МВт(?)Э
\documentclass[a5paper]{article} % a5 just to example
%\usepackage{fontspec} % commented to speed up compilation
\usepackage{tikz}
\usetikzlibrary{shapes.misc}
\usetikzlibrary{calc}
\usepackage{anyfontsize}
\usepackage{eso-pic}
\newcommand{\showgrid}{%
% \AddToShipoutPicture{%
\begin{tikzpicture}[overlay,remember picture]
\draw[blue!30!white]
(current page.south west) grid[step=1mm]
(current page.north east);
\draw[blue!80!white]
(current page.south west) grid[step=10mm]
(current page.north east);
\foreach \step in {0,1,...,297} {
\node [anchor=north] at ($ (current page.north west) + (\step mm,0cm) $) {\fontsize{1}{2}\selectfont \step};
\node [anchor=west] at ($ (current page.north west) + (0cm,-\step mm) $) {\fontsize{1}{2}\selectfont \step};
}
\end{tikzpicture}
% }%
}
\begin{document}
\thispagestyle{empty}
\begin{tikzpicture}[overlay,remember picture,every node/.style={fill=red,inner sep=0pt,outer sep=0pt}]%
\node [minimum width=2cm,minimum height=2cm] at (current page.center) {};
\end{tikzpicture}%
\showgrid
\end{document}
решение4
Вот решение, которое использует afterpage package и переопределяет команду \@outputpage. Может быть, кто-то может исправить эту команду с помощью etoolbox. Она не использует текущую страницу.
\documentclass{article}
\usepackage{tikz}
\usepackage{afterpage}
\usetikzlibrary{calc}
\usepackage{anyfontsize}
\makeatletter
\newcommand{\showgrid}{%
\let\grid@outputpage\@outputpage
\def\@outputpage{%
\begingroup % the \endgroup is put in by \aftergroup
\let \protect \noexpand
\@resetactivechars
\global\let\@@if@newlist\if@newlist
\global\@newlistfalse
\@parboxrestore
\shipout \vbox{%
\set@typeset@protect
\aftergroup \endgroup
\aftergroup \set@typeset@protect
% correct? or just restore by ending
% the group?
\if@specialpage
\global\@specialpagefalse\@nameuse{ps@\@specialstyle}%
\fi
\if@twoside
\ifodd\count\z@ \let\@thehead\@oddhead \let\@thefoot\@oddfoot
\let\@themargin\oddsidemargin
\else \let\@thehead\@evenhead
\let\@thefoot\@evenfoot \let\@themargin\evensidemargin
\fi
\fi
\reset@font
\normalsize
\normalsfcodes
\let\label\@gobble
\let\index\@gobble
\let\glossary\@gobble
\baselineskip\z@skip \lineskip\z@skip \lineskiplimit\z@
\@begindvi
\vskip \topmargin
\moveright\@themargin \vbox {%
\setbox\@tempboxa \vbox to\headheight{%
\vfil
\color@hbox
\normalcolor
\hb@xt@\textwidth{\@thehead}%
\color@endbox
}% %% 22 Feb 87
\dp\@tempboxa \z@
\box\@tempboxa
\vskip \headsep
\box\@outputbox
\baselineskip \footskip
\color@hbox
\normalcolor
\hb@xt@\textwidth{\@thefoot}%
\color@endbox
}%
\vskip-\dimexpr\textheight+\topmargin+\headheight+\headsep+\footskip+1in\relax%
\hspace*{-1in}%
\begin{tikzpicture}[every node/.style={inner sep=0pt,outer sep=0pt}]%
\draw[help lines,gray!25] (0,0) grid[step=1mm] (\paperwidth,-\paperheight);
\draw[help lines,gray] (0,0) grid[step=10mm] (\paperwidth,-\paperheight);
\foreach \step in {0,1,...,297} {
\node [anchor=north] at ($ (0,0) + (\step mm,0cm) $) {\fontsize{1}{2}\selectfont \step};
\node [anchor=west] at ($ (0,0) + (0cm,-\step mm) $) {\fontsize{1}{2}\selectfont \step};
}
\end{tikzpicture}
}%
\global\let\if@newlist\@@if@newlist
\global \@colht \textheight
\stepcounter{page}%
\let\firstmark\botmark
}\afterpage{\global\let\@outputpage\grid@outputpage}}
\makeatother
\begin{document}
\thispagestyle{empty}
test
\showgrid
and test
\begin{tikzpicture}[overlay,remember picture,every node/.style={fill=red,inner sep=0pt,outer sep=0pt}]%
\node [minimum width=2cm,minimum height=2cm] at (current page.center) {};
\end{tikzpicture}%
\newpage
test
\newpage
test
\showgrid
and test
\end{document}