我目前正在尝试创建单位正方形中随机分布的点的图像。如果这些点位于内切圆内,我想用给定的颜色绘制它们,否则,则用另一种颜色绘制它们。
这是我所得到的,没有设置条件。
\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
作为默认值,并且/.try
仅my 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}