为 tikz calc 坐标计算定义替代符号

为 tikz calc 坐标计算定义替代符号

我想为 tikz calc 坐标计算定义一个替代符号:比如说,

    ($ (a,b) + (c,d) $)

类似于

    \tzcalc{ (a,b) + (c,d) }
    

但我遇到了一个错误,我不知道如何纠正。

(我想这样做是为了区分 tikz 计算和要排版的数学。这将使编写正则表达式以仅匹配数学变得更加容易。)

我天真地定义了一个新命令:

    \newcommand{\tzcalc}[1]{($ #1 $)}

有时它会起作用。

这是我所得到的。不起作用的部分是\coordinate最后的语句。(已标记。)

    \documentclass[12pt]{amsart}

    \usepackage{tikz}

    \usetikzlibrary{calc}

    \newcommand{\tzcalc}[1]{($#1$)}

    \newcommand{\newcoord}[2]{\coordinate (#1) at ($#2$) ; } % this works.

    \begin{document}

    \begin{center}
    \begin{tikzpicture}

        \node [left] (a) at \tzcalc{ (0,0) + (135:4) + (45:2) } {$a_0$};
    
        \foreach \i in {1,...,4}
        {
            \draw \tzcalc{ (0,0) + (90:\i) } circle[radius=5pt]; % works
        }

    \end{tikzpicture}
    \end{center}

    \begin{center}
    \begin{tikzpicture}
        \newcommand{\basepointx}{2}

        \foreach \j in {0,45,90,135,180,225}
        {
            \coordinate (r\j) at \tzcalc{(\basepointx,-3) + (\j:1) }  ; % doesn't work
            % \node [coordinate] (r\j) at \tzcalc{ (\basepointx,-3) + (\j:1) }  {}; % works
            % \newcoord{r\j}{(\basepointx,-3) + (\j:1)} % works
        }

        \foreach \j in {0,45,90,135}
        {
            \draw (r\j) -- (-5,2);
        }

    \end{tikzpicture} 
    \end{center}
    \end{document}

错误如下:

    Runaway argument?
     \tzcalc {(\basepointx ,-3) + (\j :1) } ; \pgffor@endhook \ifx \pgffor@assign@a
    fter@code \ETC.
    ./tik2.tex:38: Paragraph ended before \tikz@@coordinate@@at was complete.
    <to be read again> 
                       \par 
    l.38    
  
    I suspect you've forgotten a `}', causing me to apply this
    control sequence to too much text. How can we recover?
    My plan is to forget the whole thing and hope for the best.

注意:有效,但除非必须,否则我还是会避免使用它。在我看来,如果我可以定义一个替代的命令,而不是每次收到错误时都定义 tikz 命令的替代命令,\newcoord那么会更容易。($ $)

我该如何解决这个问题?

答案1

代码

\documentclass[12pt]{amsart}
\usepackage{tikz}
\usetikzlibrary{calc}
\tikzset{every picture/.append style={execute at end picture={%
  \node[draw,lightgray]at(current bounding box){\pgfversion};}}}
\begin{document}

%%% Using the at=\tzcalc{…} syntax with an uptodate TikZ
\begingroup
  \newcommand*\tzcalc[1]{($#1$)}
  \begin{tikzpicture}
  \node [left] (a) at \tzcalc{ (0,0) + (135:4) + (45:2) } {$a_0$};
  \foreach \i in {1,...,4}
    \draw \tzcalc{ (0,0) + (90:\i) } circle[radius=5pt];
  \end{tikzpicture}
  
  \begin{tikzpicture}
  \newcommand{\basepointx}{2}
  
  \foreach \j in {0,45,90,135,180,225}
    \coordinate[at=\tzcalc{(\basepointx,-3) + (\j:1)}] (r\j);
    % Alternative:
    % \coordinate[at/.expanded=\tzcalc{(\basepointx,-3) + (\j:1)}] (r\j);
  
  \foreach \j in {0,45,90,135}
    \draw (r\j) -- (-5,2);
  \end{tikzpicture}
\endgroup

%%% “Fixing” handling of coordinate path operation
  % (and possibly breaking other things)
\begingroup
  \newcommand*\tzcalc[1]{($#1$)}
  \makeatletter
  \def\tikz@@coordinate@@at[#1](#2)at{%
    \def\tikz@coordinate@caller{\tikz@fig ode[shape=coordinate,#1](#2)at}%
    \tikz@scan@one@point\tikz@@coordinate@at@math
  }
  \makeatother
  \begin{tikzpicture}
  \node [left] (a) at \tzcalc{ (0,0) + (135:4) + (45:2) } {$a_0$};
  \foreach \i in {1,...,4}
    \draw \tzcalc{ (0,0) + (90:\i) } circle[radius=5pt];
  \end{tikzpicture}
  
  \begin{tikzpicture}
  \newcommand{\basepointx}{2}
  
  \foreach \j in {0,45,90,135,180,225}
    \coordinate (r\j) at \tzcalc{(\basepointx,-3) + (\j:1)};
  
  \foreach \j in {0,45,90,135}
    \draw (r\j) -- (-5,2);
  \end{tikzpicture}
\endgroup

%%% Adjusting \tzcalc definition/usage
  % and “fixing” $ detection
\begingroup
  \newcommand*\tzcalc[1]{$#1$}
  \makeatletter
  \let\origtikz@@@scan@@absolute\tikz@@@scan@@absolute
  \def\tikz@@@scan@@absolute#1(#2){%
    \edef\tikz@temp{#2}%
    \expandafter\origtikz@@@scan@@absolute\expandafter#1\expandafter(\tikz@temp)
  }%
  \makeatother
  \begin{tikzpicture}
  \node [left] (a) at (\tzcalc{ (0,0) + (135:4) + (45:2) }) {$a_0$};
  \foreach \i in {1,...,4}
    \draw (\tzcalc{ (0,0) + (90:\i) }) circle[radius=5pt];
  \end{tikzpicture}
  
  \begin{tikzpicture}
  \newcommand{\basepointx}{2}
  
  \foreach \j in {0,45,90,135,180,225}
    \coordinate (r\j) at (\tzcalc{(\basepointx,-3) + (\j:1)});
  
  \foreach \j in {0,45,90,135}
    \draw (r\j) -- (-5,2);
  \end{tikzpicture}
\endgroup
\end{document}

相关内容