避免在 TikZ 中对同一张图片重复代码块

避免在 TikZ 中对同一张图片重复代码块

作为我上一个问题的后续(Tikz 中的美国阿比林拓扑:如何进一步改善图片),我想优化上一篇文章(第 2 部分)中的代码。它包含相同的代码块(用于链集)的重复,以实现三幅这样的图片。我遇到了一些与我的问题密切相关的问题,但我想像我在上一篇文章中所做的那样,在一个图像上实现所有三个块,但不要重复太多代码。万一,我必须描绘 10 或 20 个这样的链,我不想复制粘贴相同的块 20 次。我尝试使用 \tikzset 命令,但我也遇到了一些麻烦。

答案1

我不确定你为什么要定义宏,而这些宏的唯一目的似乎是将其参数作为键传递给 tikz 命令。据我所知,这样做的主要目的是混淆代码。如果你想使用这样的命令,最好遵循 percusse 的建议,将pgfkeys大多数参数作为关键字传递。然而,在你的情况下,大多数参数似乎都是固定的,所以我不确定你为什么要将它们作为参数传递,而不是将它们硬编码到宏中。

我可能不会定义宏,而是可能只定义一种可用于所有节点的样式:

\tikzset{mynode/.style = {draw, drop shadow={opacity=.15}, minimum height=7, minimum width=30, %
            xslant=-2, yslant=0, inner color=#1!20, outer color=#1!45, color=#1!50!black}}

您始终可以覆盖不适用于特定节点的任何部分,但这提供了一个良好的默认起点,以避免复制/粘贴代码。

为避免重复代码,您可以采取的另一项措施是使用 pgf 的\foreach循环,它非常灵活。我建议查看文档(tikz/pgf 手册第 83 节)以了解更多功能\foreach

总的来说,我可能会将你的第二部分写成

\documentclass[tikz, border=5]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes,shadows,calc}
\usetikzlibrary{arrows, automata}

\tikzset{mynode/.style = {draw, drop shadow={opacity=.15}, minimum height=7, minimum width=30, %
            xslant=-2, yslant=0, inner color=#1!20, outer color=#1!45, color=#1!50!black}}
\begin{document}
\begin{tikzpicture}[auto, outer sep=3pt, node distance=2cm, >=latex']

% Background
\node[mynode=gray,drop shadow={opacity=.35},minimum height=100,minimum width=450, inner color=white, outer color=gray!30] {}; %

\foreach \x/\y/\edgestyle in {0.4/0/dashed, 2.8/-1.2/, 5.2/-2.4/dotted}{
  \begin{scope}[xshift=\x cm, yshift=\y cm]

    % Start
    \path (-9.7,1.20) node[mynode=red] (l) {} node {\tiny $\textit{e}_1$}; %

    % Middle
    \foreach \vx/\vy [count=\n] in {-7.2/1.20, -2.7/1.50, -4.2/0.90, -0.2/0.90, 2.00/1.20}{
      \path (\vx,\vy) node[mynode=blue] (vl\n) {} node {\tiny $\textit{vnf}_\n$}; %
    }

    % End
    \path (4.2,1.20) node[mynode=red] (r) {} node {\tiny $\textit{e}_2$}; %

    % Edges
    \foreach \u/\v in {l/vl1, vl1/vl2, vl1/vl3, vl3/vl4, vl2/vl5, vl4/vl5, vl5/r}{
      \draw [<->, thick, \edgestyle] (\u) -- (\v);
    }
  \end{scope}
}
\end{tikzpicture}

\end{document}

答案2

您可以整理宏的定义及其用法。例如,对于宏,您将拥有:

\def\comn#1[#2,#3,#4,#5,#6,#7,#8]#9{%
   \node[#1,draw,drop shadow={opacity=.15},minimum height=#2,minimum width=#3,xslant=#4,yslant=#5] (#7) at #8 {}; %
   \node[anchor=#6, inner sep=2pt] at(#7.#6) {#9};}
\def\layr{\comn{inner color=white!40,outer color=gray!30,color=gray!50!black}}
\def\endr{\comn{inner color=red!20,outer color=red!45,color=red!50!black}}
\def\vnfr{\comn{inner color=blue!20,outer color=blue!45,color=blue!50!black}}

对于图纸本身中的重复块也可以这样做。

抽象出重复块需要每次添加一个隐藏参数。其他一切都没有变化。如果基本宏中的参数用完了(比如说需要超过九个),那么你可以从这里

相关内容