在条件命令上:比 \ifnum 更强大

在条件命令上:比 \ifnum 更强大

根据TEX 简介,Petr Olšák,第 16/29 页,我们得到:

\ifnum ⟨数字 1⟩ ⟨relation⟩ ⟨数字 2⟩ 。⟨relation⟩ 可以是 < 或 = 或 >。如果两个数字的比较结果为真,则返回 true。

我正在寻找一个更强大的条件命令来包含(~=)(不等于)关系。

  • 我们有这样的条件命令吗?

我问这个问题的原因与 TikZ 手册第 1005/1318 页有关。我稍微修改了代码以生成椭圆形对象数组,如下所示:

在此处输入图片描述

我将所有椭圆顺时针旋转了 45 度。我想要做的是不旋转黄色突出显示的椭圆,以便rot=0它们。

  • 如何使用条件命令来实现?

下面是我的代码:

 \documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
 \foreach \x in {1,...,4}
\foreach \y in {1,...,4}

{
\fill[red!50] (\x,\y) ellipse [x radius=3pt, y radius=6pt, rotate=-45];
\ifnum {\x<\y} & {\x>1}
\breakforeach
\fi
}
\draw [|-|] (.895,1) -- ++(0.211,0);
\end{tikzpicture}
\end{document}

看来 ifthen 包就是答案。我使用 \ifthenelse 执行了以下代码,但出现错误:

\documentclass{standalone}
\usepackage{tikz,ifthen}
\begin{document}
\ifthenelse{1>2 \AND 3=3}{yes}{no}
\begin{tikzpicture}
\foreach \x in {1,...,4}
\foreach \y in {1,...,4}
{
\newcommand{\first}{\(\x=1 \and \y=1\)}
\newcommand{\second}{\(\x=2 \and \y=1\) }
\ifthenelse{\(\first\) \or \(\second\)}
 {\fill[red!50] (\x,\y) ellipse [x radius=3pt , y radius= 6pt, rotate=0];}
{\fill[red!50] (\x,\y) ellipse [x radius=3pt , y radius= 6pt, rotate=-45];}
\ifnum \x<\y
\breakforeach
\fi
}
\draw [|-|] (.895,1) -- ++(0.211,0);
\end{tikzpicture}
\end{document}

错误:!额外 \or. ...=1) } \ifthenelse {(\first ) \or (\second )} {\fill [red!... 您知道如何调试此代码以使其正常工作吗?

答案1

为了重现图像,测试应该是 1 ≤ x < y。

您可以参数化旋转角度并测试两种特殊情况。

\documentclass{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\foreach \x in {1,...,4} {
  \foreach \y in {1,...,4} {
    \def\rotation{-45}
    \ifnum\y=1
      \ifnum\x=1 \def\rotation{0} \fi
      \ifnum\x=2 \def\rotation{0} \fi
    \fi
    \fill[red!50] (\x,\y) ellipse [x radius=3pt, y radius=6pt, rotate=\rotation];
    \ifnum \x<\y \unless\ifnum \x<1 \breakforeach \fi\fi
  }
}
\draw [|-|] (.895,1) -- ++(0.211,0);
\end{tikzpicture}
\end{document}

在此处输入图片描述

\ifthenelse当然,您也可以使用。

\documentclass{standalone}
\usepackage{tikz}
\usepackage{xifthen}

\begin{document}
\begin{tikzpicture}
\foreach \x in {1,...,4} {
  \foreach \y in {1,...,4} {
    \ifthenelse{\y=1 \AND \(\x=1 \OR \x=2\)}{\def\rotation{0}}{\def\rotation{-45}}
    \fill[red!50] (\x,\y) ellipse [x radius=3pt, y radius=6pt, rotate=\rotation];
    \ifthenelse{ \x<\y \AND \NOT\(\x<1\) }{\breakforeach}{}
  }
}
\draw [|-|] (.895,1) -- ++(0.211,0);
\end{tikzpicture}
\end{document}

使用更简单的语法,参见https://tex.stackexchange.com/a/467527/4427

\documentclass[border=4]{standalone}
\usepackage{tikz}
\usepackage{xparse}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\xifthenelse}{mmm}
 {
  \bool_if:nTF { #1 } { #2 } { #3 }
 }

\cs_new_eq:NN \numtest     \int_compare_p:n
\cs_new_eq:NN \oddtest     \int_if_odd_p:n
\cs_new_eq:NN \fptest      \fp_compare_p:n
\cs_new_eq:NN \dimtest     \dim_compare_p:n
\cs_new_eq:NN \deftest     \cs_if_exist_p:N
\cs_new_eq:NN \namedeftest \cs_if_exist_p:c
\cs_new_eq:NN \eqdeftest   \token_if_eq_meaning_p:NN
\cs_new_eq:NN \streqtest   \str_if_eq_p:ee
\cs_new_eq:NN \emptytest   \tl_if_blank_p:n
\prg_new_conditional:Nnn \xxifthen_legacy_conditional:n { p,T,F,TF }
 {
  \use:c { if#1 } \prg_return_true: \else: \prg_return_false: \fi:
 }
\cs_new_eq:NN \boolean \xxifthen_legacy_conditional_p:n
\ExplSyntaxOff

\begin{document}
\begin{tikzpicture}
\foreach \x in {1,...,4} {
  \foreach \y in {1,...,4} {
    \xifthenelse{\numtest{\y=1} && (\numtest{\x=1} || \numtest{\x=2})}
      {\def\rotation{0}}
      {\def\rotation{-45}}
    \fill[red!50] (\x,\y) ellipse [x radius=3pt, y radius=6pt, rotate=\rotation];
    \xifthenelse{ \numtest{1<=\x<\y} }{\breakforeach}{}
  }
}
\draw [|-|] (.895,1) -- ++(0.211,0);
\end{tikzpicture}
\end{document}

答案2

LaTeX 的 ifthen 包具有一些将条件与\andand\or\not括号组合起来的功能。但您的情况很容易用 来处理\ifnum

\ifnum \x<\y \ifnum \x>1
  \breakforeach
\fi\fi

答案3

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{math}
\begin{document}
\begin{tikzpicture}
\foreach \x in {1,...,4} {
\tikzmath {\xEnd=\x+1;}
\foreach \y in {1,...,\xEnd} {
\fill[red!50] (\x,\y) 
ellipse [x radius=3pt, y radius=6pt, rotate={ifthenelse(\x==1 || \x==2 && \y==1,0,-45)}];
}}
\draw [|-|] (.895,1) -- ++(0.211,0);
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案4

找到了一个更简单的解决方案。以下是关键思想:

  • \ifthenelse如果那么CTAN 中的包就是那个强大的条件命令。

  • \ifthenelse{<test>}{<then clause>}{<else clause>}是命令格式,其中是使用中缀连接词、、、一元词 和括号的<test>布尔表达式。\and\or\not\( \)

  • 此外,与使用 and 相比,使用 and 更安全\OR,因为当它出现在具有不同含义的 TEX 条件中时不会被误解。因此,代码如下:\AND\ifthenelse\or\and\or

    \documentclass{standalone}
    \usepackage{tikz,ifthen}
    \begin{document}
    \begin{tikzpicture}
    \foreach \x in {1,...,4}
    \foreach \y in {1,...,4}
    {
    \ifthenelse{\(\x=1 \AND \y=1\) \OR \(\x=2 \AND \y=1\) }
    {\fill[red!50] (\x,\y) ellipse [x radius=3pt , y radius= 6pt, rotate=0];}
    {\fill[red!50] (\x,\y) ellipse [x radius=3pt , y radius= 6pt, rotate=-45];}
    \ifnum \x<\y
    \breakforeach
    \fi
    }
     \draw [|-|] (.895,1) -- ++(0.211,0);
    \end{tikzpicture}
    \end{document}
    

在此处输入图片描述

相关内容