TikZ 中的条件语句

TikZ 中的条件语句

我尝试if在我的 TikZ 图片中使用。例如,我只想在原点处绘制一个点1 < 2。例如,我可以这样做:

\begin{tikzpicture}
    if 1 < 2 then
        \fill (0, 0) circle (1pt);
\end{tikzpicture}

这段代码可以正常工作。但如果我尝试if在循环中使用,那么一切都会停止工作。例如,以下代码将绘制 5 个点,而不是 1 个

\begin{tikzpicture}
    \foreach \i in {1, ..., 5}
        if \i < 2 then
            \fill (\i, 0) circle (1pt);
\end{tikzpicture}

我做错了什么以及如何使代码正常工作?

我在网上唯一能找到的是这个答案,据此可以实现如下期望,但是代码太过繁琐。

\begin{tikzpicture}
    \foreach \i in {1, ..., 5} {
        \pgfmathparse{ifthenelse(\i<2, 1, 0)}
        \ifodd\pgfmathresult\relax
            \fill (\i, 0) circle (1pt);
        \fi
    }
\end{tikzpicture}

答案1

该包ifthen具有最自然的语法(在我看来)。

\ifthenelse{<boolean>}{<do this if true>}{<do this if false>}

请注意,要使用\foreach,必须将循环括在括号中,除非它是单个 tikz 命令(例如\draw)。

在此处输入图片描述

\documentclass{article}

\usepackage{tikz,ifthen}

\begin{document}

\begin{tikzpicture}
    \foreach \i in {1, ..., 5}{
        \ifthenelse{\i < 3}{\fill (\i, 0) circle (1pt);}{}
    }
\end{tikzpicture}

\end{document}

答案2

我可以提供一组更灵活的功能,请参阅https://tex.stackexchange.com/a/467527/4427

\documentclass{article}
\usepackage{tikz}

\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_empty_p:n
\cs_new_eq:NN \blanktest   \tl_if_blank_p:n
\cs_new_eq:NN \boolean     \legacy_if_p:n
\cs_new:Npn \modetest #1
 {
  \str_case:nnF { #1 }
   {
    {h}{\mode_if_horizontal_p:}
    {v}{\mode_if_vertical_p:}
    {m}{\mode_if_math_p:}
    {i}{\mode_if_inner_p:}
   }
   {\c_false_bool}
 }
\cs_new:Npn \enginetest #1
 {
  \str_case:nnF { #1 }
   {
    {luatex}{\sys_if_engine_luatex_p:}
    {pdftex}{\sys_if_engine_pdftex_p:}
    {ptex}{\sys_if_engine_ptex_p:}
    {uptex}{\sys_if_engine_uptex_p:}
    {xetex}{\sys_if_engine_xetex_p:}
   }
   {\c_false_bool}
 }

\ExplSyntaxOff

\begin{document}

\begin{tikzpicture}
\foreach \i in {1,...,8}{
  \xifthenelse{\numtest{ 2 <= \i < 5 }}
   {
    \fill (\i, 0) circle (1pt);
   }
   {
    \draw (\i, 0) circle (1pt);
   }
}
\foreach \i in {1,...,8}{
  \xifthenelse{ \numtest{ 3 < \i < 6 } || \numtest{ \i>7 } }
   {
    \fill (\i, 1) circle (1pt);
   }
   {
    \draw (\i, 1) circle (1pt);
   }
}
\end{tikzpicture}

\end{document}

在此处输入图片描述

答案3

请尝试以下操作:

\documentclass[margin=3mm]{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}     
\foreach \i in {1, ..., 5}
{              % <---
\ifnum \i < 3  % <---             
\fill (\i, 0) circle (1pt);
\fi            % <---
}              % <---
\end{tikzpicture} 
\end{document}

在此处输入图片描述

或者

\documentclass[margin=3mm]{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}     
\foreach \i in {1, ..., 5}
{         
\ifnum \i < 3              
    \fill (\i, 0) circle (1pt);
\else
    \draw (\i, 0) circle (1pt);
\fi
}
\end{tikzpicture} 
\end{document}

在此处输入图片描述

答案4

请注意 OP 代码中的 TikZ

\begin{tikzpicture}
    if 1 < 2 then
        \fill (0, 0) circle (1pt);
\end{tikzpicture}

TikZ 会忽略它,if 1 < 2 then因为它是错误的语法;事实上,如果你写逆不等式if 1 > 2 then,那么代码仍然可以使用相同的输出。TikZ 会忽略一些错误的语法错误。但 Asymptote 的情况并非如此。

我觉得这个问题很有趣。我将分享一些关于使用 TikZ 编程/绘图的个人感受,并与 Asymptote 进行比较。让我们从代码示例开始手册,第 88 节重复事物:Foreach 语句。

在此处输入图片描述

\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\foreach \x in {1,...,4}
\foreach \y in {1,...,4}
{
    \fill[red!50] (\x,\y) ellipse (3pt and 6pt);
    \ifnum \x<\y
    \breakforeach
    \fi
}
\end{tikzpicture}
\hspace*{5mm}
\begin{tikzpicture}
\foreach \x in {1,...,4}
\foreach \y in {1,...,4}
{
    \ifnum \x>\y
    \fill[blue!50] (\x,\y) ellipse (3pt and 6pt);
    \fi
    \ifnum \x=\y
    \fill[cyan!50] (\x,\y) ellipse (3pt and 6pt);
    \fi
    \pgfmathparse{\y-1}
    \ifnum \x=\pgfmathresult
    \fill[magenta!50] (\x,\y) ellipse (3pt and 6pt);
    \fi
}
\end{tikzpicture}
\hspace*{5mm}
\begin{tikzpicture}
\foreach \x in {1,...,4}
\foreach \y in {1,...,4}
{
\pgfmathparse{\x>=\y-1}
\ifnum \pgfmathresult=1
    \fill[violet!50] (\x,\y) ellipse (3pt and 6pt);
\fi
}
\end{tikzpicture}
\end{document}

附录

在此处输入图片描述

// http://asymptote.ualberta.ca/
unitsize(1cm);
int n=5;
for(int i=1;i<n;++i)
for(int j=1;j<n;++j)
if (i>=j-1) fill(ellipse((i,j),3pt/cm,6pt/cm),orange);

(待续)

相关内容