我刚刚回答了我前段时间在这里提出的一个问题: 将矩形分成 n x k 个相等的单元格。我希望能够在单独的宏中生成点列表,但是如果我只是将列表放入宏中,例如
\newcommand{\testlist}{1/2}
并且做
\rectDiv{7}{5}{(1,1)}{(4,3)}{\testlist}
我得到以下信息:
因此,似乎 1/2 被解释为坐标 (0.5,0.5)。如果我有 2/0 之类的值,则会因为除以零而出现编译器错误。
为什么\newcommand{\testlist}{1/2} \rectDiv{7}{5}{(1,1)}{(4,3)}{\testlist}
不等于\rectDiv{7}{5}{(1,1)}{(4,3)}{1/2}
?
我如何修改示例以便能够将点列表放入宏中作为最后一个参数\rectDiv
?
我也尝试过\def
,\edef
但\newcommand
没有成功。
答案1
如果使用,\foreach \i/\j in {1/2} { .. }
则\foreach
宏可以看到分隔符/
,然后拆分1
和2
。但是,如果两者都隐藏在宏中\testlist
(定义为1/2
),则它找不到分隔符并假定只使用单个值。因此,\testlist
将视为\i
和\j
视为空。
您需要\testlist
先展开,或者使用\foreach \i/\j in \testlist
,因为\foreach
定义为接受宏反而的{ }
論點。
扩展工作如下:
\edef\@tempa{\noexpand\foreach \noexpand\i/\noexpand\j in {\testlist, ..}}
\@tempa { <loop content> }
它与多个列表宏一起工作并假设\makeatletter
和\makeatother
围绕代码。
完整示例:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\def\rectDiv#1#2#3#4#5{%#columns, #rows, rectangle start, rectangle end, list of elements to fill
\begin{tikzpicture}
\draw #3 rectangle #4;
\path #3;
\pgfgetlastxy{\firstx}{\firsty}
\path #4;
\pgfgetlastxy{\secondx}{\secondy}
\pgfmathsetlengthmacro{\xdiff}{\secondx-\firstx}
\pgfmathsetlengthmacro{\ydiff}{\secondy-\firsty}
\pgfmathsetlengthmacro{\myxstep}{\xdiff/#1}
\pgfmathsetlengthmacro{\myystep}{\ydiff/#2}
\foreach \x in {1,...,#1}{
\draw ($#3 +\x*(\myxstep,0)$) -- ($#3 +(0,\ydiff) +\x*(\myxstep,0)$);
}
\foreach \y in {1,...,#2}{
\draw ($#3 +\y*(0,\myystep)$) -- ($#3 +(\xdiff,0) +\y*(0,\myystep)$);
}
\edef\temp{\noexpand\foreach \noexpand\i/\noexpand\j in {#5}}
\temp{
\path[fill=blue!20,draw] ($#3 + (\i*\myxstep,\j*\myystep)$) rectangle ($#3 + (\i*\myxstep,\j*\myystep) + (\myxstep,\myystep)$);
}
\end{tikzpicture}
}
\begin{document}
\rectDiv{7}{5}{(1,1)}{(4,3)}{0/0,1/1,2/0,5/3}
\def\list{1/0}
\rectDiv{7}{5}{(1,1)}{(4,3)}{\list}
\rectDiv{7}{5}{(1,1)}{(4,3)}{\list,2/0,5/3}
\end{document}
或者:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\def\rectDiv#1#2#3#4#5{%#columns, #rows, rectangle start, rectangle end, list of elements to fill
\begin{tikzpicture}
\draw #3 rectangle #4;
\path #3;
\pgfgetlastxy{\firstx}{\firsty}
\path #4;
\pgfgetlastxy{\secondx}{\secondy}
\pgfmathsetlengthmacro{\xdiff}{\secondx-\firstx}
\pgfmathsetlengthmacro{\ydiff}{\secondy-\firsty}
\pgfmathsetlengthmacro{\myxstep}{\xdiff/#1}
\pgfmathsetlengthmacro{\myystep}{\ydiff/#2}
\foreach \x in {1,...,#1}{
\draw ($#3 +\x*(\myxstep,0)$) -- ($#3 +(0,\ydiff) +\x*(\myxstep,0)$);
}
\foreach \y in {1,...,#2}{
\draw ($#3 +\y*(0,\myystep)$) -- ($#3 +(\xdiff,0) +\y*(0,\myystep)$);
}
\edef\list{#5}
\foreach \i/\j in \list {
\path[fill=blue!20,draw] ($#3 + (\i*\myxstep,\j*\myystep)$) rectangle ($#3 + (\i*\myxstep,\j*\myystep) + (\myxstep,\myystep)$);
}
\end{tikzpicture}
}
\begin{document}
\rectDiv{7}{5}{(1,1)}{(4,3)}{0/0,1/1,2/0,5/3}
\def\alist{1/0}
\rectDiv{7}{5}{(1,1)}{(4,3)}{\alist}
\def\blist{5/3}
\rectDiv{7}{5}{(1,1)}{(4,3)}{\alist,2/0,\blist}
\end{document}