如何在两个图形分区之间随机放置边?

如何在两个图形分区之间随机放置边?

我有两个节点 (V1) 和 (V2)(代表图形顶点集),我想在它们之间绘制 10 条边(线)。我不想对随机位置进行硬编码,所以我这样做了:

\begin{pgfonlayer}{bg} % so they don't overlap the graphic representation of V1 and V2
    \draw (V1)+(rand*.3,rand*.3) -- (V2)+(rand*.3,rand*.3);
    \draw (V1)+(rand*.3,rand*.3) -- (V2)+(rand*.3,rand*.3);
    \draw (V1)+(rand*.3,rand*.3) -- (V2)+(rand*.3,rand*.3);
    %   ... repeat more 7 times ... (PS:I know tikz has a repeat/foreach/... command - 
\end{pgfonlayer}

复制粘贴只是因为懒惰)

这种方法存在两个问题:

  1. (主要内容)线条在 V1 中从随机位置开始,但如果是 V2,它们总是在中心结束 --- 就好像 rnd 是返回 0在那些情况下。
  2. (没那么重要)使用 \pause 时,下一张幻灯片上的值会再次随机化,而我的情况并不理想。我意识到我应该以某种方式存储这些随机值,以免发生这种情况。但就我个人而言,如果这样做会使解决方案变得更加困难,我宁愿不解决它。
  3. (好的,额外加一)有没有办法在下一张幻灯片上(即暂停后)更改这些边缘的样式(即,将它们变成虚线)。 (显然,\draw[\alt{2}{...}{...}]不起作用..

答案1

可能的解决方案:

\documentclass{beamer}
\usepackage{lmodern}
\usepackage{tikz}
\usetikzlibrary{backgrounds,calc}

\begin{document}

\begin{frame}
\begin{tikzpicture}
\node[circle,draw,fill=white](V1)at (0,0){V$_1$};
\node[circle,draw,fill=white](V2)at (2,2){V$_2$};
\pgfmathsetseed{12345}
\foreach \step/\style in {1/solid,2/,3/dashed,4/solid,5/solid,6/loosely dotted,7/dashdotted,8/solid,9/dashdotted,10/dashdotted}{
\begin{pgfonlayer}{background}
\draw<\step->[\style] (V1)+(rnd*.3,rnd*.3) -- ($(V2)+(rnd*.3,rnd*.3)$);
\end{pgfonlayer}
}
\end{tikzpicture}
\end{frame}

\end{document}

结果:

在此处输入图片描述

要点:

  1. 使用\pgfmathsetseed相同的种子来生成随机数:这使得边在连续叠加之间不会改变;
  2. 使用循环设置覆盖和边缘的样式;
  3. 利用该calc库(有关更多详细信息,请参阅 pgfmanual 第 134 页)来计算最终点,否则它将是节点 V2 的中心(因为坐标不再更新)。

版本 2

正如 Qrrbrbirlbel 所建议的那样,通过提供边缘的样式,变量\step就不再需要了。

新代码为:

\documentclass{beamer}
\usepackage{lmodern}
\usepackage{tikz}
\usetikzlibrary{backgrounds,calc}

\begin{document}

\begin{frame}
\begin{tikzpicture}
\node[circle,draw,fill=white](V1)at (0,0){V$_1$};
\node[circle,draw,fill=white](V2)at (2,2){V$_2$};
\pgfmathsetseed{12345}
\foreach \style in {solid,,dashed,solid,solid,loosely dotted,dashdotted,solid,dashdotted,dashdotted}{
\begin{pgfonlayer}{background}
\draw<+->[\style] (V1)+(rnd*.3,rnd*.3) -- ($(V2)+(rnd*.3,rnd*.3)$);
\end{pgfonlayer}
}
\end{tikzpicture}
\end{frame}

\end{document}

注意:此解决方案是相等的到上一个。它还允许不在循环中指定样式,并且solid将自动应用默认样式。

答案2

除了已经说过的内容之外,这里还有一个calc解决方案,它模拟了边界查找过程--,并随机化了线条开始和结束处的节点角度锚点。当然,根据节点的形状和大小以及函数的幅度rand,线条可能会再次突出到节点中。

代码

\documentclass{beamer}
\usepackage{lmodern,tikz}
\usetikzlibrary{calc}
\tikzset{
  rand --/.style={
    to path={
      let \p{aux@direc}=($(\tikztotarget)-(\tikztostart)$),
          \n{aux@direc}={atan2(\p{aux@direc})} in
      (\tikztostart.\n{aux@direc}+rand*#1) --
      (\tikztotarget.180+\n{aux@direc}+rand*#1) \tikztonodes
    }
  }
}
\begin{document}
\begin{frame}
\begin{tikzpicture}\pgfmathsetseed{130537}
\node[circle,draw] (V1) at (0,0) {V$_1$}; \node[circle,draw] (V2) at (2,2) {V$_2$};
\foreach \cnt in {1,...,10} \draw<+-> (V1) to[rand --=10] (V2);

\tikzset{xshift=2cm}
\node[circle,draw] (V1) at (0,0) {V$_1$}; \node[circle,draw] (V2) at (2,2) {V$_2$};
\foreach \cnt in {1,...,10} \draw<+-> (V1) to[rand --=50] (V2);

\tikzset{xshift=2cm}
\node[circle,draw] (V1) at (0,0) {V$_1$}; \node[circle,draw] (V2) at (2,2) {V$_2$};
\foreach \cnt in {1,...,10} \draw<+-> (V1) to[rand --=90] (V2);

\tikzset{xshift=2cm}
\node[draw] (V1) at (0,0) {V$_1$};        \node[draw] (V2) at (2,2) {V$_2$};
\foreach \cnt in {1,...,10} \draw<+-> (V1) to[rand --=50] (V2);
\end{tikzpicture}
\end{frame}
\end{document}

输出

在此处输入图片描述

相关内容