我是 LaTeX 的初学者,在使用宏方面遇到了问题。
假设我创建了一个绘制矩形的宏。
\documentclass[10pt,a4paper, landscape]{book}
\usepackage{tikz}
\usepackage[french]{babel}
\begin{document}
\newcommand\rect[4]{
\draw (#1,#2) rectangle (#3,#4);}
\begin{tikzpicture}
\rect{1}{2}{3}{4};
\end{tikzpicture}
\end{document}
成功了。现在我想创建一个宏来连接两个矩形的第一个顶点。我在网上搜索,找到了一种获取矩形第一个顶点坐标的方法。
\documentclass[10pt,a4paper, landscape]{book}
\usepackage{tikz}
\usepackage[french]{babel}
\begin{document}
\def\generatex#1#2{%
\begingroup
\toks0={#2}%
\edef\next{\def\expandafter\noexpand\csname varx#1\endcsname{\the\toks0 }}%
\expandafter\endgroup\next}
\def\generatey#1#2{%
\begingroup
\toks0={#2}%
\edef\next{\def\expandafter\noexpand\csname vary#1\endcsname{\the\toks0 }}%
\expandafter\endgroup\next}
\newcommand\rect[5]{
\draw (#1,#2) rectangle (#3,#4);
\generatex{#5}{#1};
\generatey{#5}{#2};}
\begin{tikzpicture}
\rect{1}{2}{3}{4}{rectone};
\rect{10}{5}{2}{3}{recttwo};
\draw(\varxrectone,\varyrectone)--(\varxrecttwo,\varyrecttwo);
\end{tikzpicture}
\end{document}
这又起作用了。但是,假设我想定义一个通用宏来执行此操作。我尝试了以下操作,但不起作用:
\documentclass[10pt,a4paper, landscape]{book}
\usepackage{tikz}
\usepackage[french]{babel}
\begin{document}
\def\generatex#1#2{%
\begingroup
\toks0={#2}%
\edef\next{\def\expandafter\noexpand\csname varx#1\endcsname{\the\toks0 }}%
\expandafter\endgroup\next}
\def\generatey#1#2{%
\begingroup
\toks0={#2}%
\edef\next{\def\expandafter\noexpand\csname vary#1\endcsname{\the\toks0 }}%
\expandafter\endgroup\next}
\newcommand\rect[5]{
\draw (#1,#2) rectangle (#3,#4);
\generatex{#5}{#1};
\generatey{#5}{#2};}
\newcommand\join[2]{
\draw(\varx#1,\vary#1)--(\varx#2,\vary#2);}
\begin{tikzpicture}
\rect{1}{2}{3}{4}{rectone};
\rect{10}{5}{2}{3}{recttwo};
\join{rectone}{recttwo};
\end{tikzpicture}
\end{document}
有什么想法吗?我是 LaTeX 新手,我确信我写的都很糟糕,但请不要评判我!谢谢!!
答案1
代替
\newcommand\join[2]{
\draw(\varx#1,\vary#1)--(\varx#2,\vary#2);}
您需要使用\csname ... \endcsname
来根据其名称构造控制序列。例如,\csname varx#1\endcsname
。
\@nameuse{<csname>}
当你需要频繁使用结构时,LaTeX2e 的内部宏很有用\csname ... \endcsname
。比如,你可以写
\makeatletter
\newcommand\join[2]{
\draw(\@nameuse{varx#1},\@nameuse{vary#1})--(\@nameuse{varx#2},\@nameuse{vary#2});}
\makeatother
进一步简化的例子:
\documentclass[10pt,a4paper, landscape]{book}
\usepackage{tikz}
\usepackage[french]{babel}
\newcommand\rect[5]{
\draw (#1,#2) rectangle (#3,#4);
% store #1 in macro \varx<#5>
\expandafter\def\csname varx#5\endcsname{#1};
% store #2 in macro \vary<#5>
\expandafter\def\csname vary#5\endcsname{#2};}
\newcommand{\useCoords}[1]{\useCoordX{#1}, \useCoordY{#1}}
\newcommand{\useCoordX}[1]{\csname varx#1\endcsname}
\newcommand{\useCoordY}[1]{\csname vary#1\endcsname}
\newcommand\join[2]{
\draw (\useCoords{#1}) -- (\useCoords{#2});}
\begin{document}
\begin{tikzpicture}
\rect{1}{2}{3}{4}{rectone};
\rect{10}{5}{2}{3}{recttwo};
\join{rectone}{recttwo};
\end{tikzpicture}
\end{document}
如果愿意使用 LaTeX2e 内部组件(文档macros2e
给出了很好的介绍),你可以使用
\@namedef{<cmd>} ...
取代\expandafter\def\csname <cmd>\endcsname ...
和\@nameuse{<cmd>}
取代\csname <cmd>\endcsname
。
答案2
所有这些机制都已经是 Ti 的一部分钾Z.例如,矩形连接非常简单
\documentclass[tikz,border=3mm]{standalone}
\begin{document}
\begin{tikzpicture}
\draw[local bounding box=A] (1,2) rectangle (3,4);
\draw[local bounding box=B] (10,5) rectangle (2,3);
\draw (A.south west) -- (B.south west);
\end{tikzpicture}
\end{document}
有很多带有锚点的形状。对于您描述的目的,Ti 中已经存在内置工具钾Z。