使用 TikZ 时的坐标行为

使用 TikZ 时的坐标行为

我正在尝试将节点(2)定位在与页面相关的坐标中(原点位于页面主体的左上角)。 我的代码是:

\documentclass[border=10pt,a4paper]{memoir}
\usepackage[total={16.51cm,21.59cm},
top=1.2in, left=0.9in, includefoot]{geometry}
\usepackage{tikz}
\usepackage{fancyhdr}
\usepackage{comment}
\pagestyle{fancy}
\fancyhf{}
\renewcommand{\headrulewidth}{2pt}
\renewcommand{\footrulewidth}{1pt}
\begin{document}
\begin{tikzpicture}
\node[](1) at (0cm,0cm) {1};
\node[](2) at (0.5\textwidth,-0.5\textheight) {2};
\end{tikzpicture}
\vspace{1cm}
\noindent
\end{document}

为了将节点 (2) 放置在页面中心 (0.5\textwidth,-0.5\textheight) 处,我必须在原点处创建另一个节点 (1),否则节点 (2) 将放置在 (0,0)。我希望有人能解释这种奇怪的行为。

答案1

这会在当前页面的中间放置一个节点(您需要编译两次):

\documentclass{article}
\usepackage{tikz}
\usepackage{lipsum}

\begin{document}

\lipsum[1]

\begin{tikzpicture}[remember picture, overlay]
\node[draw] at (current page.center) {Here I am!};
\end{tikzpicture}

\lipsum[2]


\end{document}

请注意,TikZ 图片位于正常文本流之外。您可以替换current page.center为例如current page.north west以获取页面的左上角。

答案2

您观察到的行为完全正常。要理解这一点,我建议您阅读使用环境创建图片Z 和 PGF 手册(适用于 PGF/Ti 手册Z 3.1.3 [当前],第 126 和 127 页应该对您最有趣)。

基本上,tikzpicture环境会为 TeX 生成一个框,类似于字符框或使用命令创建的框\includegraphics(不要与环境混淆figure)。此框的大小由您在环境内绘制的内容决定tikzpicture:默认情况下,边界框tikzpicture是一个矩形,其边与页面边缘平行,刚好足够大保存环境中绘制的所有内容(TiZ & PGF 手册提到,由于曲线控制点和尚未绘制的类似东西会对边界框产生影响,因此可能会出现一些细微的变化,但这显然不是这里的问题)。除非您使用该baseline选项,否则创建的框的基线将与我刚才描述的矩形的下边重合。

因此,如果您只绘制节点(2),则整体tikzpicture只是一个足够容纳此节点的小框——它并不比普通字符框大很多(默认情况下,节点内容周围有一些填充,但与您的\textwidth或相比没有什么可比性\textheight)。它被 TeX 放置的方式与您输入A(例如)而不是整个 的方式相同tikzpicture。您设置 Ti 的事实Z 原点,所以它(0.5\textwidth,-0.5\textheight)位于小节点的中心,这无论如何都无关紧要。这就是为什么我说我的评论的参考点tikzpicture不一定在(0,0)。坐标并不重要,除了:

  • 用于内部元素的相对定位tikzpicture

  • 如果你使用该baseline选项,y坐标确实很重要(baseline=y0使基线与相对于 Ti 的tikzpicture方程线重合y=y0Z 原点,有关详细信息,请参阅我上面提到的手册部分)。

当您同时拥有两个节点时,情况就完全不同了:最小的封闭矩形的尺寸约为 0.5 \textwidth×0.5 \textheight:它不再是一个与字形大小相当的小矩形了\normalsize!因此,在某种程度上,您的节点(1)会将节点(2)向下和向右推,这是因为我已解释过 的边界框和基线的规则tikzpicture,以及 TeX 有关段落中框的规则(这里的段落仅由一个框组成,在您的示例中还有缩进框)。框太高了,以至于 TeX 的有关规则\topskip会在文本区域顶部和 的顶部之间放置一个长度为零的垂直粘连。tikzpicture但是,在您的示例中,框的左侧tikzpicture位于\parindent左边距,而不是零。此外,您的(0,0)原点位于节点 的中心(1),而 的上边缘(1)与上边距重合,正如我关于 所述\topskip

下面是使用您的方法但纠正了所有这些小缺陷的代码,将节点的中心(2)精确地放置在文本区域的中心:

\documentclass{article}
\usepackage{tikz}

% Shows the limits of the text area (among others)
\usepackage{showframe}
\renewcommand\ShowFrameLinethickness{0.15pt}
\renewcommand*\ShowFrameColor{\color{blue!30}}

\begin{document}

\noindent
\begin{tikzpicture}
  \node[minimum width=0, minimum height=0, inner sep=0, outer sep=0] (1)
    at (0,0) {};
  \node[draw] (2) at (0.5\textwidth,-0.5\textheight)
    {center of text area};
\end{tikzpicture}

\end{document}

手动放置

这非常准确,但会在页面上放置一个非常大的框,如果您还打算在整个文本区域中排版文本,这可能会不方便。这是上一种方法的变体,不占用空间(请注意偏移量\topskip,这是必要的,因为此时框的高度为零,因此其基线位于\topskip文本区域顶部以下):

\documentclass{article}
\usepackage{tikz}

% Shows the limits of the text area (among others)
\usepackage{showframe}
\renewcommand\ShowFrameLinethickness{0.15pt}
\renewcommand*\ShowFrameColor{\color{blue!30}}

\begin{document}

\noindent
\begin{tikzpicture}[overlay]
  \node[minimum width=0, minimum height=0, inner sep=0, outer sep=0] (1)
    at (0,0) {};
  \node[draw] (2) at (0.5\textwidth,-0.5\textheight+\topskip)
    {center of text area};
\end{tikzpicture}

\end{document}

(没有截图,因为它与前一个完全相同)

但是使用该软件包还有一种更简单的方法tikzpagenodes

\documentclass{article}
\usepackage{tikz}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc}

% Shows the limits of the text area (among others)
\usepackage{showframe}
\renewcommand\ShowFrameLinethickness{0.15pt}
\renewcommand*\ShowFrameColor{\color{blue!30}}

\begin{document}

\begin{tikzpicture}[remember picture, overlay]
  \coordinate (center)
    at ($(current page text area.south west) !0.5!
         (current page text area.north east)$);
  \node[draw, red!40!black] (label) at (center) {center of text area};
  \draw[blue!30] (current page text area.south west)
              -- (current page text area.north east)
                 (current page text area.north west)
              -- (current page text area.south east);
\end{tikzpicture}

\end{document}

(由于remember picture需要机制才能tikzpagenodes正常工作,因此需要运行两次编译)

使用 tikzpagenodes 包的技术

最后,我们可以在同一页面上使用这两种方法来证明它们给出完全相同的结果(编译两次;您只会看到中心的一个方框文本,但它实际上是从两个地方以两种不同的颜色绘制的!):

\documentclass{article}
\usepackage{tikz}
\usepackage{tikzpagenodes}
\usetikzlibrary{calc}

% Shows the limits of the text area (among others)
\usepackage{showframe}
\renewcommand\ShowFrameLinethickness{0.15pt}
\renewcommand*\ShowFrameColor{\color{blue!30}}

\begin{document}

\noindent
\begin{tikzpicture}[overlay]
  \node[minimum width=0, minimum height=0, inner sep=0, outer sep=0] (1)
    at (0,0) {};
  \node[draw, blue] (2) at (0.5\textwidth,-0.5\textheight+\topskip)
    {center of text area};
\end{tikzpicture}

\begin{tikzpicture}[remember picture, overlay]
  \coordinate (center)
    at ($(current page text area.south west) !0.5!
         (current page text area.north east)$);
  \node[draw, red!40!black] (label) at (center) {center of text area};
  \draw[blue!30] (current page text area.south west)
              -- (current page text area.north east)
                 (current page text area.north west)
              -- (current page text area.south east);
\end{tikzpicture}

\end{document}

笔记:

  • 出于与上述相同的原因,这需要两次编译运行。

  • 没有屏幕截图,因为它与前一个完全相同,因为第二个屏幕tikzpicture截图绘制在第一个屏幕截图的顶部。

相关内容