保持圆形和矩形之间的固定比例

保持圆形和矩形之间的固定比例

我正在尝试创建一个由圆形和正方形组成的 10x10 网格,其中对象的位置是随机分配的。

例如,以下代码创建一个 10x10 的网格,其中 80% 是圆形,20% 是正方形,但位置不是随机的:

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
  \foreach \x in {1,2,3,4,5,6,7,8,9,10}{
    \foreach \y in {3,4,5,6,7,8,9,10}{
    \begin{scope}[shift={(2*\x,2*\y)}]
      \node[circle,draw,minimum size =1.25cm,fill=black] (c) at (0,0){};
    \end{scope}
    }
  }
  \foreach \x in {1,2,3,4,5,6,7,8,9,10}{
    \foreach \y in {1,2}{
    \begin{scope}[shift={(2*\x,2*\y)}]
      \node[rectangle,draw,minimum size =1.25cm,fill=black] (c) at (0,0){};
    \end{scope}
    }
  }
\end{tikzpicture}
\end{document}

图像如下所示:

在此处输入图片描述

是否可以让 tikz 随机分配对象/节点的位置?

答案1

欢迎来到 TeX.SE。有多种可能性,其中包括\pgfmathrandom和方便的 ( \pgfmathdeclarerandomlist, \pgfmathrandomitem) 对。以下是使用后者的解决方案:

\documentclass[tikz,border=2mm]{standalone}

\begin{document}
\begin{tikzpicture}
  \pgfmathdeclarerandomlist{shapes}{{circle}{rectangle}}
  \foreach \x in {1,...,10} {
    \foreach \y in {1,...,10} {
      \pgfmathrandomitem{\myShape}{shapes}
      \node[\myShape, draw, minimum size=1.25cm, fill=black] at (2*\x,2*\y) {};
    }
  }
\end{tikzpicture}
\end{document}

在此处输入图片描述

如果各种图片的代码更难分解,您可以使用相同的技术,在和之间随机\macroA选择\macroB

\pgfmathdeclarerandomlist{mymacros}{{\macroA}{\macroB}}

...

\pgfmathrandomitem{\randMacro}{mymacros}
\randMacro

保持圆形和矩形之间的固定比例

根据您的评论,我们现在将重点获取 80% 的圆形和 20% 的矩形。

概率方法

在这种方法中,每次我们将一个项目添加到“画布”时,都会随机选择其形状,圆形的概率为 0.8,矩形的概率为 0.2。在这些条件下,当绘制 100 个项目时,圆圈的数量可以是 0 到 100 之间的任何数字(包括 0 和 100);获得的圆圈数量遵循二项分布带有参数n = 100 且 =0.8)。

为了实现这一点,您可以重复使用以前的技术,输入列表例如包含四个circle元素和一个rectangle元素。这是另一种使用random()(即\pgfmathrandom)的方法,它返回 0 到 1 之间的随机浮点数(具有均匀分布):

\documentclass[tikz,border=2mm]{standalone}

\begin{document}
\begin{tikzpicture}
  \pgfmathdeclarerandomlist{shapes}{{circle}{rectangle}}
  \foreach \x in {1,...,10} {
    \foreach \y in {1,...,10} {
      \pgfmathsetmacro{\myShape}{(random() < 0.8) ? "circle" : "rectangle"}
      \node[\myShape, draw, minimum size=1.25cm, fill=black] at (2*\x,2*\y) {};
    }
  }
\end{tikzpicture}
\end{document}

在此处输入图片描述

注意:使用此方法时,随机种子似乎每分钟都会发生变化(使用 pdfTeX 引擎进行测试)。从Z 和 PGF 手册

在此处输入图片描述

精确方法

使用以下代码,如果您绘制 100 个项目,其中 80 个将是圆形,20 个将是矩形。此方法的工作原理是创建一个包含 100 个项目(80 个circle和 20 个rectangle项目)的列表,随机打乱此列表,然后逐个弹出每个项目。

\documentclass[tikz,border=2mm]{standalone}

\ExplSyntaxOn

% We need global assignments for this sequence because \foreach executes each
% iteration in its own group.
\seq_new:N \g_dave_shapes_seq

\cs_new_protected:Npn \dave_init_shapes:
  {
    \seq_gclear:N \g_dave_shapes_seq
    \int_step_inline:nn { 80 }
      { \seq_gput_right:Nn \g_dave_shapes_seq { circle } }
    \int_step_inline:nn { 20 }
      { \seq_gput_right:Nn \g_dave_shapes_seq { rectangle } }
    \seq_gshuffle:N \g_dave_shapes_seq
  }

\msg_new:nnn { dave } { no-more-items }
  { No~ more~ items~ in~ the~ \token_to_str:N #1 sequence. }

\cs_new_protected:Npn \dave_pop_one_shape:N #1
  {
    \seq_gpop_left:NN \g_dave_shapes_seq #1
    \quark_if_no_value:NT #1
      { \msg_error:nnn { dave } { no-more-items } { \g_dave_shapes_seq } }
  }

\cs_new_eq:NN \initShapes \dave_init_shapes:
\cs_new_eq:NN \popOneShape \dave_pop_one_shape:N

\ExplSyntaxOff

\begin{document}
\begin{tikzpicture}
  \initShapes

  \foreach \x in {1,...,10} {
    \foreach \y in {1,...,10} {
      \popOneShape{\myShape}
      \node[\myShape, draw, minimum size=1.25cm, fill=black] at (2*\x,2*\y) {};
    }
  }
\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容