在这个例子中,我想在每个宏中创建通用名称(对于用户而言)的节点\N{a}
,\N{b}
...但命名不同(对于 tikz),以避免在连续调用宏时混淆和覆盖。
节点(tikz 端)的名称是,a-i-x
其中i
是调用宏的叠覆级别,x
是用户使用时给出的名称\N{x}
。
我尝试过这个,但是由于宏的扩展,存在一些不便。当我将节点传递给下一个宏时,我必须预测未来的扩展,并且必须使用不同的宏来引用此节点\Np{x}
。
在下面的例子中,我更喜欢使用\Middles[\N{b},\N{c},\N{d}](#2,#3,#4)
而不是使用\Middles[\Np{b},\Np{c},\Np{d}](#2,#3,#4)
如何统一语法?
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{quotes}
% counter for naming nodes
\newcounter{LittNode}
% level of calling
\pgfmathtruncatemacro{\NumNode}{1}
% node named #1 at the current level
\newcommand{\N}[1]{a-\NumNode-#1}
% node named #1 at the previous level
\newcommand{\Np}[1]{a-\NumNodep-#1}
% Pass the created nodes back to the calling macro
\newcommand{\KeepUsefullNodes}[1]{%
%
\setcounter{LittNode}{1}
\foreach \Nd in {#1} {%
\coordinate (\Nd) at (\N{\alph{LittNode}}) ;
\stepcounter{LittNode}
}
\pgfmathtruncatemacro{\NumNode}{\NumNode-1}
}
% one level up at the begining of a macro
\newcommand{\AtBeginTikzMacro}{%
\pgfmathtruncatemacro{\NumNodep}{\NumNode}
\pgfmathtruncatemacro{\NumNode}{\NumNode+1}
}
%-----------------------------------------------------------
\def\tr[#1](#2,#3,#4){\draw[#1] (#2) -- (#3) -- (#4) --cycle;}
\def\drawpoints(#1){%
\foreach \pt in {#1} {\fill (\pt) circle (2 pt);}}
\def\labelpoints(#1){%
\foreach \pt in {#1} {\path coordinate["\pt" below] () at (\pt) ;}}
%-----------------------------------------------------------
%-------------------------------------------------------------
\def\Middles[#1](#2,#3,#4){
% new level of nodes
\AtBeginTikzMacro
\path[coordinate](barycentric cs:#2=1,#3=1) coordinate (\N{c});
\path[coordinate](barycentric cs:#2=1,#4=1) coordinate (\N{b});
\path[coordinate](barycentric cs:#3=1,#4=1) coordinate (\N{a});
\KeepUsefullNodes{#1}
}
%-------------------------------------------------------------
%-------------------------------------------------------------
\def\Medians[#1](#2,#3,#4){
% new level of nodes
\AtBeginTikzMacro
% use of `\Np{b}` ... to anticipate the expansion
\Middles[\Np{b},\Np{c},\Np{d}](#2,#3,#4)
% and refer now by `\N{b}` to the same node
\path[coordinate](barycentric cs:\N{b}=1,\N{c}=1,\N{d}=1) coordinate (\N{a});
\draw[green] (#2)--(\N{b}) (#3)--(\N{c}) (#4)--(\N{d});
\KeepUsefullNodes{#1}
}
%-------------------------------------------------------------
\begin{document}
\begin{tikzpicture}
\path coordinate (a) at (0,1)
coordinate (b) at (5,2)
coordinate (c) at (1,6);
\tr[red](a,b,c)
% as final use
% we take the three middles with human names
%\Middles[I,J,K](a,b,c)
%\tr[blue](I,J,K)
\Medians[G,I,J,K](a,b,c)
\tr[blue](I,J,K)
\drawpoints(G)
\labelpoints(G)
\end{tikzpicture}
\end{document}
答案1
完全可定制且人类可读的节点名称,不同宏之间没有交互。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{quotes}
\makeatletter
\newcommand{\NewPoints}[1]{%
\expandafter\edef\csname #1\endcsname{%
a-\NumNode-\theLittNode}
\stepcounter{LittNode}
%}
}
\makeatother
% counter for naming nodes
\newcounter{LittNode}
% level of calling
\pgfmathtruncatemacro{\NumNode}{0}
% node named #1 at the current level
\def\N#1{a-\NumNode-#1}
% Pass the created nodes back to the calling macro
\newcommand{\KeepUsefullNodes}{%
\edef\Sortie{\csname OutPut-\NumNode \endcsname}
\foreach \Nd [count=\i from 1]
in \Sortie {%
\coordinate (\Nd) at (\N{\i}) ;
% debbuging
%\node at (2*\NumNode,\i/2) {\Nd -- \N{\i}} ;
}
\pgfmathtruncatemacro{\NumNode}{\NumNode-1}
}
% one level up at the begining of a macro
\newcommand{\AtBeginTikzMacro}[1]{%
\pgfmathtruncatemacro{\NumNodep}{\NumNode}
\pgfmathtruncatemacro{\NumNode}{\NumNode+1}
\expandafter\xdef\csname OutPut-\NumNode\endcsname{#1}
\setcounter{LittNode}{1}
}
%-----------------------------------------------------------
\def\tr[#1](#2,#3,#4){\draw[#1] (#2) -- (#3) -- (#4) --cycle;}
\def\drawpoints(#1){%
\foreach \pt in {#1} {\fill (\pt) circle (2 pt);}}
\def\labelpoints(#1){%
\foreach \pt in {#1} {\path coordinate["\pt" below] () at (\pt) ;}}
%-----------------------------------------------------------
%-------------------------------------------------------------
\def\Middles[#1](#2,#3,#4){
\AtBeginTikzMacro{#1}
\NewPoints{A}
\NewPoints{B}
\NewPoints{C}
\path[coordinate](barycentric cs:#2=1,#3=1) coordinate (\C);
\path[coordinate](barycentric cs:#2=1,#4=1) coordinate (\B);
\path[coordinate](barycentric cs:#3=1,#4=1) coordinate (\A);
\KeepUsefullNodes
}
%-------------------------------------------------------------
%-------------------------------------------------------------
\def\Medians[#1](#2,#3,#4){
\AtBeginTikzMacro{#1}
% human compatible node name
% In in the order of their output
\NewPoints{Gravite}
\NewPoints{A}
\NewPoints{B}
\NewPoints{C}
\Middles[\A,\B,\C](#2,#3,#4)
\tr[blue](\A,\B,\C)
\path[coordinate](barycentric cs:\A=1,\B=1,\C=1) coordinate (\Gravite);
\draw[green] (#2)--(\A) (#3)--(\B) (#4)--(\C);
\KeepUsefullNodes
}
%-------------------------------------------------------------
\begin{document}
\begin{tikzpicture}
\path coordinate (a) at (0,1)
coordinate (b) at (5,2)
coordinate (c) at (1,6);
\tr[red](a,b,c)
% as final use
% we take the three middles with human names
%\Middles[I,J,K](a,b,c)
%\tr[blue](I,J,K)
\Medians[G,I,J,K](a,b,c)
\tr[blue](I,J,K)
\drawpoints(G)
\labelpoints(G)
\end{tikzpicture}
\end{document}