作为一名课程助教,我正在尝试为教授绘制座位表。座位表上将包含每个学生的照片、学生姓名以及学生在教室中的座位位置。
使用 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
... ),则可以使用计数器:image2
image3
\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)
位于页面的左下角。让我提出两项单独的增强措施:
不用冗长的路径,而是使用
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 left
和trim right
)。您想将其放置
(0,0)
在页面的左下角吗?那就将其移到那里吧!使用特殊节点
current page
和选项overlay
,remember 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}