防止 tikz 计算

防止 tikz 计算

我刚刚回答了我前段时间在这里提出的一个问题: 将矩形分成 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宏可以看到分隔符/,然后拆分12。但是,如果两者都隐藏在宏中\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}

相关内容