我正在寻找一种方法来有条件地处理 TikZ 中的某些项目,\foreach
特别是使用\ifthenelse
条件。但是,编译器响应
! Undefined control sequence.
<argument> \isin
在处理此文档时。
\documentclass{standalone}
\usepackage{tikz, xifthen}
\newcommand\groupedges[2]{
\begin{tikzpicture}
\foreach \name/\position in {a/30, b/40, c/20}
\node (\name) at (\position:5cm) {\name};
\foreach \name/\position in {d/120, e/150, f/170, g/90, h/100}
\node (\name) at (\position:5cm) {\name};
\node (left) at (-1, 0) {left};
\node (right) at (1, 0) {right};
\foreach \name in {#1}
\path (\ifthenelse{\isin{\name}{#2}}{right}{left}) edge (\name);
\end{tikzpicture}
}
\begin{document}
\groupedges{a,b,d,e,g,h}{abc}
\end{document}
我最初考虑用 pgfkeys 来表达条件,但发现这太麻烦了,尤其是在使用时\newcommand
,我需要用它来作为更复杂的预期情况的示例。
我也尝试使用纯 TeX 来实现它,它有一个\ifin@
条件。这会导致同样的错误。
TikZ 和 ifthen(或 xifthen)可以组合吗?有没有简单的 pgfkeys 或纯 TeX 解决方案?或者甚至可能有更多建议来实施\foreach
元素上的决策?
答案1
编辑(2017):答案的后半部分已损坏,因为从那时起xint 1.1 (2014/10/28)
包xint
就无法加载。代码已更新为直接使用包。xinttools
xinttools
很可能,问题在于这些测试的(不)可扩展性。但你可以这样做 [感谢版主纠正了edge
,我从 OP 那里复制粘贴了内容,没有仔细检查]
\documentclass{standalone}
\usepackage{tikz, xifthen}
\newcommand\groupedges[2]{
\begin{tikzpicture}
\foreach \name/\position in {a/30, b/40, c/20}
\node (\name) at (\position:5cm) {\name};
\foreach \name/\position in {d/120, e/150, f/170, g/90, h/100}
\node (\name) at (\position:5cm) {\name};
\node (left) at (-1, 0) {left};
\node (right) at (1, 0) {right};
\foreach \name in {#1}
{\ifthenelse{\isin{\name}{#2}}{\path (right) edge (\name);}
{\path (left) edge (\name);}}
\end{tikzpicture}
}
\begin{document}\thispagestyle{empty}%
\groupedges{a,b,d,e,g,h}{abc}
\end{document}
(更新后的图片)
但显然,这并不像预期的那样有效。因此,我被迫再次为信特 :)
:
\documentclass{standalone}
\usepackage{tikz, xifthen}
\usepackage{xinttools}
\newcommand\groupedges[2]{%
\begin{tikzpicture}
\foreach \name/\position in {a/30, b/40, c/20}
\node (\name) at (\position:5cm) {\name};
\foreach \name/\position in {d/120, e/150, f/170, g/90, h/100}
\node (\name) at (\position:5cm) {\name};
\node (left) at (-1, 0) {left};
\node (right) at (1, 0) {right};
% \foreach \name in {#1}
% {\ifthenelse{\isin{\name}{#2}}{\path (right) edge (\name);}
% {\path (left) edge (\name);}}
\xintFor ##1 in {#1}
\do {\ifthenelse{\isin{##1}{#2}}{\path (right)}
{\path (left)} edge (##1);}
\end{tikzpicture}%
}
\begin{document}\thispagestyle{empty}%
\groupedges{a,b,d,e,g,h}{abc}
\end{document}
答案2
两点评论:
\isin
似乎不可能将其放入路径命令中。因此您必须这样做(如@jfbu 所建议的):
{\ifthenelse{...}{\path (右) 边 (\name);} {\path (左) 边缘 (\name);}}
- 为了能够使用,
\isin{\name}{#2}
您必须先扩展\name
它,然后将其传递给\isin
像这样\expandafter\isin\name{#2}
,最后您可以这样做:
{\ifthenelse{\expandafter\isin\name{#2}}{\path (右) 边 (\name);} {\path (左) 边缘 (\name);}}
以下是对我有用的完整代码:
\documentclass{独立} \usepackage{tikz, xifthen} \newcommand\groupedges[2]{ \开始{tikzpicture} \foreach \name/\position 在 {a/30, b/40, c/20} \node(\name)位于(\position:5cm){\name}; \foreach \name/\position 在 {d/120, e/150, f/170, g/90, h/100} \node(\name)位于(\position:5cm){\name}; \node(左)位于(-1,0){left}; \node(右)位于(1,0){右}; \foreach \name 在 {#1} {\ifthenelse{\expandafter\isin\name{#2}}{\path (右) 边 (\name);} {\path (左) 边缘 (\name);}} \结束{tikzpicture} } \开始{文档} \groupedges{a,b,d,e,g,h}{abc} \结束{文档}