代码:

代码:

作为一名课程助教,我正在尝试为教授绘制座位表。座位表上将包含每个学生的照片、学生姓名以及学生在教室中的座位位置。

使用 TikZ 中的标签和锚点,我可以手动为每个学生创建一个标签,并使用该标签将学生的姓名与学生的图像锚定在一起。

\documentclass[12pt]{article}

\usepackage[margin=0in,paperwidth=17in, paperheight=11in]{geometry}
\usepackage{tikz}

\begin{document}

\begin{center}
\begin{tikzpicture}
  \draw[white] (0,0) -- (43.1,0) -- (43.1,27.9) -- (0,27.9) -- (0,0);

  \node[anchor=base,inner sep=0] (image1) at (4,4)
      {\includegraphics[width=25mm]{empty-face.png}};
  \node[text width=30mm,align=center,anchor=north] at (image1.south)
      {George Washington};

  \node[anchor=base,inner sep=0] (image2) at (8,4)
      {\includegraphics[width=25mm]{empty-face.png}};
  \node[text width=30mm,align=center,anchor=north] at (image2.south)
      {John Adams};

  \node[anchor=base,inner sep=0] (image3) at (12,4)
      {\includegraphics[width=25mm]{empty-face.png}};
  \node[text width=30mm,align=center,anchor=north] at (image3.south)
      {Thomas Jefferson};

\end{tikzpicture}
\end{center}

\end{document}

最小工作示例的部分输出

\student但是,由于班上有 70 名学生,定义一个新命令来定位学生的脸部和姓名似乎更为优雅。更具体地说,我希望以下代码能够工作。

\documentclass[12pt]{article}

\usepackage[margin=0in,paperwidth=17in, paperheight=11in]{geometry}
\usepackage{tikz}

% Usage: \student{x coord}{y coord}{name}{picture file}
\newcommand{\student}[4]{
% What should I put in here????
}

\begin{document}

\begin{center}
\begin{tikzpicture}
  \draw[white] (0,0) -- (43.1,0) -- (43.1,27.9) -- (0,27.9) -- (0,0);

  \student{4}{4}{George Washington}{empty-face.png};
  \student{8}{4}{John Adams}{empty-face.png};
  \student{12}{4}{Thomas Jefferson}{empty-face.png};
\end{tikzpicture}
\end{center}

\end{document}

我的问题是:我应该如何定义\student命令?因为我需要它每次都生成一个新标签,以便对齐每个学生的姓名和照片。

一种可能的解决方法是让\student命令接受 5 个参数,每次我都手动指定一个新标签。但这似乎是一种笨拙且可能导致错误的方法。

答案1

您可以使用此label选项完全不使用节点名称。label选项的说明在PGF 手册在第 16.10 节“标签和引脚选项”中,第 194 页及后续页面。

如果您想要通用节点名称(如,,image1... ),则可以使用计数器:image2image3

\newcounter{qrr@imagecounter}
\newcommand{\student}[4]{% Usage: \student{x coord}{y coord}{name}{picture file}
  \stepcounter{qrr@imagecounter}%
  \node[anchor=base,inner sep=0,label={[text width=30mm,align=center]below:#3}]
    (image\the\value{qrr@imagecounter})at (#1,#2) {\includegraphics[width=25mm]{#4}};%
}

笔记

  • 删除该行\usepackage[demo]{graphicx}以包含您的实际图片,它仅用于此 MWE。
  • 我注意到了

    \draw[white] (0,0) -- (43.1,0) -- (43.1,27.9) -- (0,27.9) -- (0,0);
    

    在您的代码中除了绘制一个白色矩形(边框是白色的,该区域没有任何颜色)之外什么也不做。

    我猜你实际上是想让 TikZ 图片变大,以便坐标(0,0)位于页面的左下角。

    让我提出两项单独的增强措施:

    1. 不用冗长的路径,而是使用rectangle操作

      (0,0) rectangle (43.1,27.9)
      

      并且不要使用白色绘图,而是使用此矩形作为边界框(这实际上是您在此处执行的操作:扩展边界框,以便 TeX 看到更大的 TikZ 图片框并相应地放置它):

      \useasboundingbox (0,0) rectangle (43.1,27.9);
      

      \useasboundingbox是 的快捷方式\path[use as bounding box],这意味着您仍然可以使用矩形来绘制/填充某些内容\draw[use as bounding box, green]

      还要注意,你也可以在 TikZ 中使用所有 TeX 长度单位,你甚至可以使用

      \useasboundingbox (0,0) rectangle (17in,11in);
      

      一切正常吗?其实不然,因为我们现在有一个关于 过满的 TeX 警告\hbox。这是由于在 TikZ 图片框前面自动插入的段落缩进。\noindent在 前面添加\begin{tikzpicture}

      (我怀疑这也是您在示例中没有使用完整的原因(43.18,27.94)?此外,白色矩形的线宽(默认为 0.4 pt)增加了额外的间距,导致输出更加糟糕,一切变得更加复杂(请参阅路径说明符clip和选项trim lefttrim right)。

    2. 您想将其放置(0,0)在页面的左下角吗?那就将其移到那里吧!

      使用特殊节点current page和选项overlayremember picture我们可以做到

      \begin{tikzpicture}[overlay,remember picture,shift=(current page.south west)]
      

      它的功能与没有页面大小的边界框的相同。(在这种情况下,\noindent您可以/应该注释掉\noindent和行。)\useasboundingbox

      overlay/解决方案remember picture需要两个 LaTeX 编译(它使用.aux文件)。

    您可以添加类似

    \fill (0,0) circle (5pt);
    

    检查坐标(0,0)位于何处。

代码

\documentclass[12pt]{article}
\usepackage[demo]{graphicx}
\usepackage[margin=0in,paperwidth=17in, paperheight=11in]{geometry}
\usepackage{tikz}

% Usage: \student{x coord}{y coord}{name}{picture file}
\newcommand{\student}[4]{%
  \node[anchor=base,inner sep=0] (x) at (#1,#2)
      {\includegraphics[width=25mm]{#4}} node[text width=30mm,align=center,anchor=north] at(\tikzlastnode.south) {#3};%
}

\begin{document}
\noindent
\begin{tikzpicture}%[overlay,remember picture,shift=(current page.south west)]
  \useasboundingbox (0,0) rectangle (17in,11in);

  \student{4}{4}{George Washington}{empty-face.png};
  \student{8}{4}{John Adams}{empty-face.png};
  \student{12}{4}{Thomas Jefferson}{empty-face.png};
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

答案2

您可以使用:

% Usage: \student{x coord}{y coord}{name}{picture file}{image label}
\newcommand{\student}[5]{%
  \node[anchor=base,inner sep=0] (image#5) at (#1,#2)
      {\includegraphics[width=25mm]{#4}};
      \node[text width=30mm,align=center,anchor=north] at (image#5.south)
      {#3};
}%

代码:

\documentclass[12pt]{article}

\usepackage[margin=0in,paperwidth=17in, paperheight=11in]{geometry}
\usepackage{tikz}

% Usage: \student{x coord}{y coord}{name}{picture file}{image label}
\newcommand{\student}[5]{%
  \node[anchor=base,inner sep=0] (image#5) at (#1,#2)
      {\includegraphics[width=25mm]{#4}};
      \node[text width=30mm,align=center,anchor=north] at (image#5.south)
      {#3};
}%

\begin{document}

\begin{center}
\begin{tikzpicture}
  \draw[white] (0,0) -- (43.1,0) -- (43.1,27.9) -- (0,27.9) -- (0,0);

  \student{4}{4}{George Washington}{example-image-a}{1};
  \student{8}{4}{John Adams}{example-image-b}{2};
  \student{12}{4}{Thomas Jefferson}{example-image}{3};
\end{tikzpicture}
\end{center}

\end{document}

在此处输入图片描述

答案3

基本版本:

回答您最初的问题,#<n>当您需要nth宏的参数时只需使用即可。

在此处输入图片描述

笔记:

  • 由于您在放置图像和标签后似乎没有使用节点的名称,因此我仅将节点命名为X

进一步改进:

  • 使用\foreach循环可以进一步自动化此操作,而不必提供坐标,而只需提供两个参数:名称和图像名称。如果您同意根据学生姓名命名图像文件,则您只有一个选项:学生姓名。但由于名称可能包含许多不能用作文件名的字符,因此我实际上将图像文件名设为可选参数。

代码:

\documentclass[12pt]{article}
\usepackage[demo]{graphicx}
\usepackage[margin=0in,paperwidth=17in, paperheight=11in]{geometry}
\usepackage{tikz}

% Usage: \student{x coord}{y coord}{name}{picture file}
\newcommand{\student}[4]{%
  % What should I put in here????
  \node[anchor=base,inner sep=0] (X) at (#1,#2)
      {\includegraphics[width=25mm]{#4}};
  \node[text width=30mm,align=center,anchor=north] at (X.south)
      {#3};
}

\begin{document}

\begin{center}
\begin{tikzpicture}
  \draw[white] (0,0) -- (43.1,0) -- (43.1,27.9) -- (0,27.9) -- (0,0);

  \student{4}{4}{George Washington}{empty-face.png};
  \student{8}{4}{John Adams}{empty-face.png};
  \student{12}{4}{Thomas Jefferson}{empty-face.png};
\end{tikzpicture}
\end{center}

\end{document}

增强版:

除了创建单独的命令外,您还可以使用循环\foreach来简化操作。因此,在下面的示例中,如果您有 3 行学生,则可以将其指定为:

\newcommand*{\ListOfStudents}{%
    {George Washington, John Adams, Thomas Jefferson},%
    {Albert Einstien, Steven Hawings, Kip Thorpe},%  
    {Steve Jobs, Gil Amelio, John Scully}%   
}%

每个括号组从前到后定义一行。

在此处输入图片描述

代码:

\documentclass[12pt]{article}
\usepackage[demo]{graphicx}
\usepackage[margin=0in,paperwidth=17in, paperheight=11in]{geometry}
\usepackage{tikz}


% Usage: \student{x coord}{y coord}{name}{picture file}
\newcommand{\student}[4]{%
  % What should I put in here????
  \node[anchor=base,inner sep=0] (X) at (#1,#2)
      {\includegraphics[width=25mm]{#4}};
  \node[text width=30mm,align=center,anchor=north] at (X.south)
      {#3};
}

\newcommand*{\ListOfStudents}{%
    {George Washington, John Adams, Thomas Jefferson},%
    {Albert Einstien, Steven Hawings, Kip Thorpe},%  
    {Steve Jobs, Gil Amelio, John Scully}%   
}%

\begin{document}

\begin{center}
\begin{tikzpicture}
  \draw[white] (0,0) -- (43.1,0) -- (43.1,27.9) -- (0,27.9) -- (0,0);

    \foreach [count=\Row] \RowOfStudents in \ListOfStudents {%
        \foreach [count=\Col] \StudentName/\Image in \RowOfStudents {%
            \student{4*\Col}{5*\Row}{\StudentName}{\Image}
        }
    }%
\end{tikzpicture}
\end{center}

\end{document}

相关内容