作为我上一个问题的后续(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}}
对于图纸本身中的重复块也可以这样做。
抽象出重复块需要每次添加一个隐藏参数。其他一切都没有变化。如果基本宏中的参数用完了(比如说需要超过九个),那么你可以从这里。