需要解决依赖宏扩展顺序的症状

需要解决依赖宏扩展顺序的症状

背景:TikZ。我经常写这样的命令

\draw[->,line width=2mm] (3.3,4.3) -- (1.5,2.5) ;

在棋盘(不是国际象棋)的背景下。我想用字符串坐标替换这些点f5,比如c5,这样我就可以写成\arrow{f5,c5},这将扩展为

\draw[->,line width=2mm] (5.5,5.5) -- (2.5,5.5) ;

因为f柱子在水平距离处5.5,并且c柱子在水平距离处2.5

我尝试过什么?我尝试用宏调用代替这些坐标,但 TikZ 抱怨它无法理解坐标。在我看来,TikZ 看到的是我的宏,而不是它们的扩展。(我不会说我需要知道如何按特定顺序扩展事物,因为你可能有更好的方法来做所有事情。)


**更新**:这是一份显示主板的可编译文档。

在此处输入图片描述

\documentclass{article}

\usepackage{tikz}
\usepackage{ifthen}
\usepackage{color}

\definecolor{printgray}{rgb}{0.9,0.9,0.9}
\definecolor{black}{rgb}{0.2,0.2,0.2}

\def\labelstyle{\bf}

\makeatletter

\newcommand{\innerboard}{\begingroup
\foreach \x in {1,2,...,6}
  \foreach \y in {1,2,...,6} { %% crazy code, watch out!
    \ifthenelse{\(\isodd{\x}\and\isodd{\y}\)\OR\(\not\(\isodd{\x}\)\and\not\(\isodd{\y}\)\)}{\filldraw[fill=printgray]}{\draw} (\x, \y) rectangle +(1,-1);
  }
\endgroup}

\newcommand{\alternatexfill}[1]{\ifthenelse{\not{\isodd{#1}}}{\filldraw[fill=printgray]}{\draw}}
\newcommand{\alternatefill}[1]{\ifthenelse{\isodd{#1}}{\filldraw[fill=printgray]}{\draw}}

\newcommand{\topborder}{\begingroup
\foreach \x in {1,2,...,6} {
  \alternatefill{\x} (\x, 6) +(0, 0.2) rectangle +(1, 1+0.2);
}
\endgroup}

\newcommand{\bottomborder}{\begingroup
\foreach \x in {1,2,...,6}
  \alternatexfill{\x} (\x, -1) +(0, -0.2) rectangle +(1, 1 - 0.2);
\endgroup}

\newcommand{\leftborder}{\begingroup
\foreach \y in {0,1,...,5}
  \alternatefill{\y} (0, \y) +(-0.2, 0) rectangle +(1 - 0.2,1);
\endgroup}

\newcommand{\rightborder}{\begingroup
\foreach \y in {0,1,...,5}
  \alternatexfill{\y} (7, \y) +(0.2, 0) rectangle +(1 + 0.2,1);
\endgroup}

\newcommand{\ring}{\begingroup
  \bottomborder
  \rightborder
  \topborder
  \leftborder
\endgroup}

\newcommand{\labelstop}{\begingroup
\def\pos{8}
\draw (0, \pos) +(0.3, -0.5) node {\strut\labelstyle a};
\foreach [count=\x] \c in {b,c, ..., g}{
  \pgfmathsetmacro\label{\x + 1}
  \draw (\x, \pos) +(0.5, -0.5) node {\strut\labelstyle \c};
}
\draw (7, \pos) +(0.7, -0.5) node {\strut\labelstyle h};
\endgroup}

\newcommand{\labelsright}{\begingroup
\def\pos{8}
\draw (\pos, -1) +(0.5, 0.3) node {\strut\labelstyle 1};
\draw (\pos,  6) +(0.5, 0.7) node {\strut\labelstyle 8};
\foreach \x in {2,...,7}{
  \pgfmathsetmacro\xcoord{\x - 2}
  \draw (\pos,  \xcoord) +(0.5, 0.5) node {\strut\labelstyle \x};
}
\endgroup}

\newcommand{\labelsleft}{\begingroup
\def\pos{-0.2}
\draw (\pos, -1) +(-0.5, 0.3) node {\strut\labelstyle 1};
\draw (\pos,  6) +(-0.5, 0.7) node {\strut\labelstyle 8};
\foreach \x in {2,...,7}{
  \pgfmathsetmacro\xcoord{\x - 2}
  \draw (\pos,  \xcoord) +(-0.5, 0.5) node {\strut\labelstyle \x};
}
\endgroup}

\newcommand{\labelsbottom}{\begingroup
\def\pos{-1}
\draw (0, \pos) +(0.3, -0.5) node {\strut\labelstyle a};
\foreach [count=\x] \c in {b,c, ..., g}{
  \pgfmathsetmacro\label{\x + 1}
  \draw (\x, \pos) +(0.5, -0.5) node {\strut\labelstyle \c};
}
\draw (7, \pos) +(0.7, -0.5) node {\strut\labelstyle h};
\endgroup}

\newcommand{\labels}{\labelsleft\labelsbottom\labelsright\labelstop}

\newcommand{\board}{
  \ring
  \innerboard
  \labels
  %% show origin
  \filldraw[fill=black] (0,0) circle [radius=1pt] +(0,-0.5) node{origin};
}

\begin{document}
\begin{tikzpicture}
\ring
\board
\end{tikzpicture}

\end{document}

答案1

为了命名坐标,您可以执行以下操作:

\coordinate (⟨name⟩) at (⟨x⟩,⟨y⟩);

在下面的例子中,我引入了一个宏\introduceCoordinates,它通过循环数字 1..8 来形成 x 坐标和 y 坐标并组成 a1 或 h8 等名称,从而为您完成上述操作。

这或许是一个起点。

\documentclass{article}

\usepackage{tikz}
\usepackage{ifthen}
\usepackage{color}

\definecolor{printgray}{rgb}{0.9,0.9,0.9}
\definecolor{black}{rgb}{0.2,0.2,0.2}

\def\labelstyle{\bf}

\makeatletter

\newcommand{\innerboard}{\begingroup
\foreach \x in {1,2,...,6}
  \foreach \y in {1,2,...,6} { %% crazy code, watch out!
    \ifthenelse{\(\isodd{\x}\and\isodd{\y}\)\OR\(\not\(\isodd{\x}\)\and\not\(\isodd{\y}\)\)}{\filldraw[fill=printgray]}{\draw} (\x, \y) rectangle +(1,-1);
  }
\endgroup}

\newcommand{\alternatexfill}[1]{\ifthenelse{\not{\isodd{#1}}}{\filldraw[fill=printgray]}{\draw}}
\newcommand{\alternatefill}[1]{\ifthenelse{\isodd{#1}}{\filldraw[fill=printgray]}{\draw}}

\newcommand{\topborder}{\begingroup
\foreach \x in {1,2,...,6} {
  \alternatefill{\x} (\x, 6) +(0, 0.2) rectangle +(1, 1+0.2);
}
\endgroup}

\newcommand{\bottomborder}{\begingroup
\foreach \x in {1,2,...,6}
  \alternatexfill{\x} (\x, -1) +(0, -0.2) rectangle +(1, 1 - 0.2);
\endgroup}

\newcommand{\leftborder}{\begingroup
\foreach \y in {0,1,...,5}
  \alternatefill{\y} (0, \y) +(-0.2, 0) rectangle +(1 - 0.2,1);
\endgroup}

\newcommand{\rightborder}{\begingroup
\foreach \y in {0,1,...,5}
  \alternatexfill{\y} (7, \y) +(0.2, 0) rectangle +(1 + 0.2,1);
\endgroup}

\newcommand{\ring}{\begingroup
  \bottomborder
  \rightborder
  \topborder
  \leftborder
\endgroup}

\newcommand{\labelstop}{\begingroup
\def\pos{8}
\draw (0, \pos) +(0.3, -0.5) node {\strut\labelstyle a};
\foreach [count=\x] \c in {b,c, ..., g}{
  \pgfmathsetmacro\label{\x + 1}
  \draw (\x, \pos) +(0.5, -0.5) node {\strut\labelstyle \c};
}
\draw (7, \pos) +(0.7, -0.5) node {\strut\labelstyle h};
\endgroup}

\newcommand{\labelsright}{\begingroup
\def\pos{8}
\draw (\pos, -1) +(0.5, 0.3) node {\strut\labelstyle 1};
\draw (\pos,  6) +(0.5, 0.7) node {\strut\labelstyle 8};
\foreach \x in {2,...,7}{
  \pgfmathsetmacro\xcoord{\x - 2}
  \draw (\pos,  \xcoord) +(0.5, 0.5) node {\strut\labelstyle \x};
}
\endgroup}

\newcommand{\labelsleft}{\begingroup
\def\pos{-0.2}
\draw (\pos, -1) +(-0.5, 0.3) node {\strut\labelstyle 1};
\draw (\pos,  6) +(-0.5, 0.7) node {\strut\labelstyle 8};
\foreach \x in {2,...,7}{
  \pgfmathsetmacro\xcoord{\x - 2}
  \draw (\pos,  \xcoord) +(-0.5, 0.5) node {\strut\labelstyle \x};
}
\endgroup}

\newcommand{\labelsbottom}{\begingroup
\def\pos{-1}
\draw (0, \pos) +(0.3, -0.5) node {\strut\labelstyle a};
\foreach [count=\x] \c in {b,c, ..., g}{
  \pgfmathsetmacro\label{\x + 1}
  \draw (\x, \pos) +(0.5, -0.5) node {\strut\labelstyle \c};
}
\draw (7, \pos) +(0.7, -0.5) node {\strut\labelstyle h};
\endgroup}

\newcommand{\labels}{\labelsleft\labelsbottom\labelsright\labelstop}

\newcommand{\board}{
  \ring
  \innerboard
  \labels
  %% show origin
  \filldraw[fill=black] (0,0) circle [radius=1pt] +(0,-0.5) node{origin};
}

\makeatletter
\newcommand\expandTeXnumber[1]{%
   % Delivers with trailing space the sequence of digit-tokens 
   % that comes from a TeX-number-quantity.
   % Be aware that with LaTeX-counters you need to use
   %   \value{counter}%
   % or
   %   \arabic{counter}%
   % in order to have a TeX-number-quantity.
   \expandafter\@firstofone\expandafter{\number#1} %
}%
\newcommand\PassFirstToSecond[2]{#2{#1}}%
\newcommand\introduceCoordinates{%
  \introduceCoordinatesInRange{1}{8}{1}{8}%
}%
\newcommand\introduceCoordinatesInRange[4]{%
  % #1 - lower bound for x-component
  % #2 - upper bound for x-component
  % #3 - lower bound for y-component
  % #4 - upper bound for y-component
  \introduceCoordinatesloop{#1}{#2}{#3}{#4}{#1}{#3}%
}%
\newcommand\introduceCoordinatesloop[6]{%
  % #1 - to be incremented (lower) bound for x-component
  % #2 - upper bound for x-component
  % #3 - to be incremented (lower) bound for y-component
  % #4 - upper bound for y-component
  % #5 - lower bound for x-component
  % #6 - lower bound for y-component
  \ifnum\expandTeXnumber{#3}>\expandTeXnumber{#4}%
    \expandafter\@gobble
  \else
    \expandafter\@firstofone
  \fi{%
    \ifnum\expandTeXnumber{#1}>\expandTeXnumber{#2}%
      \expandafter\@secondoftwo
    \else
      \expandafter\@firstoftwo
    \fi{%
      %\message{\string%%%%%%%%%%%%%%%%%%%%%%%%%%
      \coordinate (\@alph{#1}#3) at %
      (%
        \ifnum\expandTeXnumber{#1}=\expandTeXnumber{#5}%
          \number\numexpr#1-1\relax.3%
        \else
          \ifnum\number\expandTeXnumber{#1}=\expandTeXnumber{#2}%
             \number\numexpr#1-1\relax.7%
           \else
             \number\numexpr#1-1\relax.5%
           \fi
        \fi
      ,%
        \ifnum\number\expandTeXnumber{#3}=\expandTeXnumber{#6}%
          -\number\numexpr#3-1\relax.7%
        \else
          \ifnum\expandTeXnumber{#3}=\expandTeXnumber{#4}%
            \number\numexpr#3-2\relax.7%
          \else
            \number\numexpr#3-2\relax.5%
          \fi
        \fi
      );%
      %}%%%%%%%%%%%%%%%%%%%%%%%
      \expandafter\PassFirstToSecond\expandafter{\number\numexpr#1+1\relax}{\introduceCoordinatesloop}{#2}{#3}{#4}{#5}{#6}%
    }{%
      \expandafter\PassFirstToSecond\expandafter{\number\numexpr#3+1\relax}{\introduceCoordinatesloop{#5}{#2}}{#4}{#5}{#6}%
    }%
  }%
}%

\makeatother


\begin{document}
\begin{tikzpicture}
\ring
\board
\introduceCoordinates
\draw[->,line width=2mm] (a1) -- (h1);
\draw[->,line width=2mm] (f2) -- (a2);
\draw[->,line width=2mm] (f3) -- (a3);
\draw[->,line width=2mm] (f4) -- (c4);
\draw[->,line width=2mm] (f5) -- (c5);
\draw[->,line width=2mm] (f6) -- (c6);
\draw[->,line width=2mm] (f7) -- (a7);
\draw[->,line width=2mm] (h8) -- (a8);
\draw[->,line width=2mm] (a1) -- (h8);
\draw[->,line width=2mm] (a8) -- (h1);
\draw[->,line width=2mm] (h7) -- (h2);
\draw[->,line width=2mm] (a4) -- (a6);
\end{tikzpicture}

\end{document}

在此处输入图片描述

相关内容