在 Tikz-Calc 中使用自定义命令

在 Tikz-Calc 中使用自定义命令

这是我在这里的第一个问题,所以我希望我能以适当的形式提出它。

目前,我正在使用 TikZ 包及其calc库生成大量示意图。因此,我经常使用坐标,在某些情况下,我必须将 x 坐标或 y 坐标设置为零。我目前使用的内容:

([yscale=0](coordiantes))

它运行完美,所以我想为此创建一个自定义命令。这也可以,但是当我尝试在计算中使用此自定义命令时,LaTeX 会给出错误:

\xCo {westPoint}$) to (westPoint); Paragraph ended before \tikz@cc@parse@factor was complete.

我已经尝试通过在几个星座中尝试括号来解决这个问题,但这也没有带来任何改善。

这是我的 MWE,具有三种使用场景(直接坐标操作、自定义命令以及计算中的自定义命令)

\documentclass{article}

%My needed packages
\usepackage{tikz}
\usetikzlibrary{calc}

%My custom command
\newcommand{\xCo}[1]{([yscale=0]#1)}

\begin{document}

\begin{tikzpicture}
%Defining coordinates
 \coordinate (westPoint) at (3,2.5);
 \coordinate (eastPoint) at (6,2.5);
% 
%Calculate the (x,0)-coordinates of 'westPoint' 
\coordinate (bottomPointA) at ($([yscale=0]westPoint)$);
%Drawing a simple line --> bottom point coordinates work
\draw (bottomPointA) to (eastPoint);
%
% NEXT VERSION --> custom command
%Drawing a simple line --> bottom point coordinates work
\draw \xCo{westPoint} to (westPoint);

%NOT working part:
\draw ($(0,1)+\xCo{westPoint}$) to (westPoint);


 \end{tikzpicture}

\end{document}

我希望有人能告诉我为什么会出现这个问题以及如何解决它。也许有比我的更好的解决方案,所以这对我来说也很有趣。

另一个听起来类似的问题是: 在 Tikz 坐标计算中使用宏 但是这个例子确实很复杂,我不确定它是否与我的问题类似。

谨致问候,MrMinion

PS:我已经知道并使用了该let \p{name} in ().... access via \x{name} or \y{name}解决方案,但它并不方便,因为我只能使用一条路径内的点。如果有人知道如何“全局”使用它们,我将不胜感激 :)。

答案1

这是一个修改 tikzcalc库以扩展宏的解决方案。

请注意,这不适用于坐标因子,因为 tikzcalc 会扫描文字来*(确定因子的结束位置,因此(不能隐藏在宏中(因此2*\xCo{point}会导致错误)。没有办法解决这个问题,除非使因子解析器变得更慢、更复杂。我相信它适用于其余语法calc

\documentclass{article}
\usepackage{etoolbox}
%My needed packages
\usepackage{tikz}
\usetikzlibrary{calc}

%My custom command
\newcommand{\xCo}[1]{([yscale=0]#1)}


\makeatletter
%% Patch a bunch of tikzcalc commands to use romannumeral trick to f expand macros
\patchcmd\tikz@cc@add{\tikz@cc@factororcoordinate}{\expandafter\tikz@cc@factororcoordinate\romannumeral-`0}{}{\error}
\patchcmd\tikz@cc@sub{\tikz@cc@factororcoordinate}{\expandafter\tikz@cc@factororcoordinate\romannumeral-`0}{}{\error}
\let\origtikz@cc@scan@rot\tikz@cc@scan@rot
\def\tikz@cc@scan@rot#1{%
    \expandafter\origtikz@cc@scan@rot\expandafter#1\romannumeral-`0%
}
\let\origtikz@cc@mid@nonactive\tikz@cc@mid@nonactive
\let\origtikz@cc@mid@active\tikz@cc@mid@active
\def\tikz@cc@mid@nonactive!{\expandafter\origtikz@cc@mid@nonactive\expandafter!\romannumeral-`0}
\edef\restorebang{\catcode`!=\the\catcode`!\relax}
\catcode`!=\active
\def\tikz@cc@mid@active!{\expandafter\origtikz@cc@mid@active\expandafter!\romannumeral-`0}
\restorebang
\makeatletter

\begin{document}

\begin{tikzpicture}
%Defining coordinates
 \coordinate (westPoint) at (3,2.5);
 \coordinate (eastPoint) at (6,2.5);
%
%Calculate the (x,0)-coordinates of 'westPoint'
\coordinate (bottomPointA) at ($([yscale=0]westPoint)$);
%Drawing a simple line --> bottom point coordinates work
\draw (bottomPointA) to (eastPoint);
%
% NEXT VERSION --> custom command
%Drawing a simple line --> bottom point coordinates work
\draw \xCo{westPoint} to (westPoint);

%% The following work due to my modification:
\draw ($(0,1)+\xCo{westPoint}$) to (westPoint);
\draw ($(1,1)+\xCo{westPoint}!0.5!(0,1)$) to (westPoint);
\draw ($(1,1)+2*(0,1)!0.5!\xCo{westPoint}$) to (westPoint);
\draw ($(1,1)+(2,0)!\xCo{westPoint}!(0,1)$) to (westPoint);

%% Does not work because it has a factor directly in front of \xCo:
%\draw ($2*\xCo{westPoint}$) to (westPoint);


 \end{tikzpicture}

\end{document} 

相关内容