我想用 tikz 创建以下图(说明总体和随机样本),其中的点是随机创建/放置的;然而,圆圈内的所有点都应该用红色表示:
使用基于以前(有点类似)的问题的答案,我能够创建以下情节。
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\draw (0,0) -- (4,0) -- (4,4) -- (0,4) -- cycle;
\foreach \x in {1,...,40}
{
\pgfmathrandominteger{\a}{10}{390}
\pgfmathrandominteger{\b}{10}{390}
\fill (\a*0.01,\b*0.01) circle (0.1);
};
\draw (2,2) circle (1cm);
\end{tikzpicture}
\end{document}
但是,我不知道如何将圆圈内的点涂成红色(我有一个模糊的想法,涉及基本几何形状,并通过检查每个点是否位于圆圈内......这有意义吗?)。
答案1
r
从数学上讲,以 为圆心,半径为 的圆(a,b)
由以下方程定义
(x-a)^2 + (y-b)^2 = r^2
因此,要检查某个点是否位于此圆内,可以检查随机点是否(x,y)
满足
(x-a)^2 + (y-b)^2 <= r^2
r
即它们距离圆心小于。如果你使用<=
,那么点在 边框仍然算作“内部”,如果你使用<
,则不会。
在 Ti 中执行此操作钾Z,可以使用ifthenelse
PGF Math提供的函数。即:
\pgfmathparse{ ifthenelse(condition, "value A", "value B")}
如果条件满足,\pgfmathresult
则包含"value A"
,如果不满足,则包含"value B"
。我们可以使用它来将颜色设置为 "black"
或"red"
:
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
% Random seed for RNG
\pgfmathsetseed{\number\pdfrandomseed}
% Define circle parameters
\newcommand{\cX}{2}
\newcommand{\cY}{2}
\newcommand{\cR}{1}
\draw (0,0) -- (4,0) -- (4,4) -- (0,4) -- cycle;
\foreach \x in {1,...,40}
{
% Find random numbers
\pgfmathrandominteger{\a}{10}{390}
\pgfmathrandominteger{\b}{10}{390}
% Scale numbers nicely
\pgfmathparse{0.01*\a}\let\a\pgfmathresult
\pgfmathparse{0.01*\b}\let\b\pgfmathresult
% Check if numbers are inside circle
\pgfmathparse{ifthenelse((\a-\cX)^2 + (\b-\cY)^2 <= \cR^2,%
"red",
"black")}
\fill[\pgfmathresult] (\a,\b) circle (0.1);
};
\draw (\cX,\cY) circle (\cR);
\end{tikzpicture}
\end{document}
答案2
如果您不介意以点为单位工作,那么 TikZmath
库可能会有所帮助。在这里,如果点位于圆的边界上,则会被拒绝。
\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{math}
\begin{document}
\begin{tikzpicture}[x=1pt,y=1pt]
\tikzmath{%
coordinate \c, \p, \q;
\q = (100, 100);
\c = (30, 30);
\R = 50;
\r = 1;
{
\draw (-\qx, -\qy) rectangle (\qx, \qy);
\draw [red] (\c) circle [radius=\R];
};
\x = \qx - \r; \y = \qy - \r;
for \i in {0,...,100}{
\p = (rand * \x, rand * \y);
\v = veclen(\cx - \px, \cy - \py);
if \v > (\R + \r) then {
{ \fill [black] (\p) circle [radius=\r]; };
} else {
if \v < (\R - \r) then {
{ \fill [red] (\p) circle [radius=\r]; };
};
};
};
}
\end{tikzpicture}
\end{document}
答案3
这是一个“剪贴蒙版”解决方案:
\documentclass[varwidth, border=7pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{fadings}
\begin{document}
% define clip mask with random points
\begin{tikzfadingfrompicture}[name=rndpts]
\fill[transparent!0] foreach ~ in {1,...,100}{(rand,rand) circle (0.02)};
\end{tikzfadingfrompicture}
% use it to clip rectangle and circle
\begin{tikzpicture}
\begin{scope}
\fill[scope fading=rndpts, fit fading=true] (0,0) rectangle (4,4);
\fill[red] (2,2) circle (1cm);
\end{scope}
\draw (0,0) rectangle (4,4);
\draw[red] (2,2) circle (1cm);
\end{tikzpicture}
\end{document}
答案4
这是另一个解决方案:
- 设置以坐标为圆心
center
,半径为\ra
(以 表示pt
)的圆。 - A
\foreach
循环创建 200 个随机点,但您可以更改该数量。 - 测量在
center
在每个点 - 使用
\if
语句,如果长度超过50pt
,则点将为标准黑色,否则,它们将被涂成红色。
输出
代码
\documentclass[margin=20pt]{standalone}
\usepackage{tikz,tkz-euclide}
\usetkzobj{all}
\usetikzlibrary{calc}
\newcommand\ra{50}
\begin{document}
\begin{tikzpicture}
\draw (1,2) coordinate (center) circle (\ra pt);
\foreach \point in {1,...,200}{%
\pgfmathparse{rand}
\pgfmathsetmacro\xdot{-7*\pgfmathresult}
\pgfmathparse{rand}
\pgfmathsetmacro\ydot{-5*\pgfmathresult}
%
\coordinate (c\point) at (\xdot,\ydot);
\tkzCalcLength(center,c\point) \tkzGetLength{myl}
\pgfmathtruncatemacro\distance{\myl}
\ifnum\distance>\ra
\fill (c\point) circle (2pt);
\else
\fill[red] (c\point) circle (2pt);
\fi
}%
\end{tikzpicture}
\end{document}