使用浮点数的条件选项在 Tikz 中绘图

使用浮点数的条件选项在 Tikz 中绘图

我目前正在尝试创建单位正方形中随机分布的点的图像。如果这些点位于内切圆内,我想用给定的颜色绘制它们,否则,则用另一种颜色绘制它们。

这是我所得到的,没有设置条件。

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{math}

\begin{document}
\begin{tikzpicture}
\fill[blue!10!white] (1,1) circle (1);
\draw[very thick] (0,0) -- (0,2) -- (2,2) -- (2,0) -- cycle;
\foreach \i in {1,...,50}{
    \tikzmath{\xa=rand;}
    \tikzmath{\ya=rand;}
    \tikzmath{\eval=int(\xa^2+\ya^2 - 1.0);}
    \fill[red!60!white](\xa+1, \ya+1) circle(1.5pt);
}
\end{tikzpicture}
\end{document}

我希望填充/圆形指令有一个颜色选项,该选项取决于\eval上面定义的值。例如:如果\eval > 0使用[red!60!white],否则,使用[blue!60!white]

我尝试使用\ifthenelse,但由于我对浮点数设置了条件,并且 ifthenelse 仅限于整数,因此遇到了错误(我想?)。

我也尝试将填充/圆形指令放入 tikzmath 环境中,并在里面设置条件,但这也不起作用,我相信是因为无法从该环境内部调用绘制指令。

如下所示:

\foreach \i in {1,...,50}{
    \tikzmath{\xa=rand;}
    \tikzmath{\ya=rand;}
    \tikzmath{\eval=int(\xa^2+\ya^2 - 1.0);}
    \tikzmath{
        if \eval < 0 then {
            \fill[CERNblue!80!white](\xa+1, \ya+1) circle(1.5pt);
        } else {
            \fill[red!60!white](\xa+1, \ya+) circle(1.5pt);
        }
    }
}

有人知道如何解决这些限制吗?

答案1

以下代码有条件地为点着色。请注意,我必须用括号括起来\x\y因为(\x)^2+(\y)^2如果它们是负数(例如 -0.5 和 -0,5),则初始表达式将扩展为,-0.5^2+-0.5^2这可能不是您期望的。此外,代码使用let将字符串分配给变量\c

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{math}

\begin{document}
\begin{tikzpicture}
\fill[blue!10!white] (1,1) circle (1);
\draw[very thick] (0,0) -- (0,2) -- (2,2) -- (2,0) -- cycle;
\foreach \i in {1,...,50}{
    \tikzmath{
      \xa = rand;
      \ya = rand;
      \eval = (\xa)^2+(\ya)^2 - 1.0;
      if \eval<0 then {
        let \c = blue!80!white;
      } else {
        let \c = red!60!white;
      };
    }
    \fill[\c](\xa+1, \ya+1) circle(1.5pt);
}
\end{tikzpicture}
\end{document}

结果: 在此处输入图片描述

答案2

您与上一个代码示例非常接近,您只需要将 TikZ 语句括在另一对中{}并添加另一个;

if \eval < 0 then {
   { \fill[blue!80!white](\xa+1, \ya+1) circle[radius=1.5pt]; };
} else {
   { \fill[red!60!white] (\xa+1, \ya+1) circle[radius=1.5pt]; };
};

你可以用文本做数学题,比如

\col = \eval ? "blue!60!white" : "red!60!white";
% or 
\col = ifthenelse(\eval, "blue!60!white", "red!60!white")

当然,你也可以这样做if

if \eval < 0 then {
  \col = "blue!60!white";% or let \col = blue!60!white;
} else {
  \col = "red!60!white"; % or let \col = red!60!white;
};

\<var> = <stuff>以评估形式进行的作业<stuff>,但您也可以let \<var> = <stuff>执行不是评估<stuff>,这样你就可以放弃"

不管怎样,现在你可以说

\fill[\col](\xa+1, \ya+1) circle[radius=1.5pt];

由于\eval是一个简单的整数,你也可以使用 TeX 基元,比如

\fill[\ifnum\eval<0 blue\else red\fi !60!white](\xa+1, \ya+1) circle[radius=1.5pt];

但这不是很好。


由于你只有两个结果取决于\eval你可以定义my fill 0/.style=red!60!white

然后使用

\fill[blue!60!white, my fill \eval/.try](\xa+1, \ya+1) circle[radius=1.5pt];

其中,blue!60!white作为默认值,并且/.trymy fill \eval在未定义样式时进行尝试并且不会抱怨。


我总是喜欢有一个if可用的键来评估语句并根据值应用不同的样式。这样,你甚至可以说

\fill[/utils/if={ int(\xa^2+\ya^2 - 1.0)<0 }% conditional
                { blue!60!white }           % if true
                { red!60!white  }           % if false
  ] (\xa+1, \ya+1) circle[radius=1.5pt];

顺便说一下,\foreach宏允许对每个循环进行数学运算,而不需要\tikzmath

\foreach[
  evaluate={
    \xa=rand;
    \ya=rand;
    \eval=int(\xa^2+\ya^2 - 1.0);
  }] \i in {1,...,50}{

代码

\documentclass[tikz]{standalone}
\usetikzlibrary{math}

\makeatletter
\pgfkeys{% always useful
  /utils/if/.code n args={3}{%
    \pgfmathparse{#1}\ifdim\pgfmathresult pt=0pt\relax
    \expandafter\pgfutil@firstoftwo
      \else\expandafter\pgfutil@secondoftwo\fi
    {\pgfkeysalso{#3}}{\pgfkeysalso{#2}}}}
\makeatother

\begin{document}
\begin{tikzpicture}
\fill[blue!10!white] (1,1) circle[radius=1];
\draw[very thick] (0,0) rectangle (2,2);
\foreach \i in {1,...,50}{
    \tikzmath{
      \xa=rand;
      \ya=rand;
      \eval=int(\xa^2+\ya^2 - 1.0);
      \col = \eval ? "blue!60!white" : "red!60!white";
    }
    \fill[\col](\xa+1, \ya+1) circle[radius=1.5pt];
}
\end{tikzpicture}

\begin{tikzpicture}
\fill[blue!10!white] (1,1) circle[radius=1];
\draw[very thick] (0,0) rectangle (2,2);
\foreach \i in {1,...,50}{
    \tikzmath{
      \xa=rand;
      \ya=rand;
      \eval=int(\xa^2+\ya^2 - 1.0);
      if \eval < 0 then {
        \col = "blue!60!white";% or let \col = blue!60!white;
      } else {
        \col = "red!60!white"; % or let \col = red!60!white;
      };
    }
    \fill[\col](\xa+1, \ya+1) circle[radius=1.5pt];
}
\end{tikzpicture}

\begin{tikzpicture}
\fill[blue!10!white] (1,1) circle[radius=1];
\draw[very thick] (0,0) rectangle (2,2);
\foreach \i in {1,...,50}{
    \tikzmath{
      \xa=rand;
      \ya=rand;
      \eval=int(\xa^2+\ya^2 - 1.0);
      if \eval < 0 then {
            {\fill[blue!80!white](\xa+1, \ya+1) circle[radius=1.5pt];};
        } else {
            {\fill[red!60!white](\xa+1, \ya+1) circle[radius=1.5pt];};
        };
    }
}
\end{tikzpicture}

\begin{tikzpicture}
\fill[blue!10!white] (1,1) circle[radius=1];
\draw[very thick] (0,0) rectangle (2,2);
\foreach \i in {1,...,50}{
    \tikzmath{
      \xa=rand;
      \ya=rand;
      \eval=int(\xa^2+\ya^2 - 1.0);
    }
    \fill[\ifnum\eval<0 blue\else red\fi !60!white](\xa+1, \ya+1) circle[radius=1.5pt];
}
\end{tikzpicture}

\begin{tikzpicture}[my fill 0/.style=red!60!white]
\fill[blue!10!white] (1,1) circle[radius=1];
\draw[very thick] (0,0) rectangle (2,2);
\foreach \i in {1,...,50}{
    \tikzmath{
      \xa=rand;
      \ya=rand;
      \eval=int(\xa^2+\ya^2 - 1.0);
    }
    \fill[blue!60!white, my fill \eval/.try](\xa+1, \ya+1) circle[radius=1.5pt];
}
\end{tikzpicture}

\begin{tikzpicture}
\fill[blue!10!white] (1,1) circle[radius=1];
\draw[very thick] (0,0) rectangle (2,2);
\foreach \i in {1,...,50}{
    \tikzmath{
      \xa=rand;
      \ya=rand;
      \eval=int(\xa^2+\ya^2 - 1.0);
    }
    \fill[/utils/if={ int(\xa^2+\ya^2 - 1.0)<0 }% conditional
                    { blue!60!white }           % if true
                    { red!60!white  }           % if false
      ] (\xa+1, \ya+1) circle[radius=1.5pt];
}
\end{tikzpicture}
\end{document}

相关内容