梅威瑟:
\documentclass{scrartcl}
\usepackage{tikz}
\tikzset{
signal/.style = coordinate,
block/.style = {
draw,
rectangle,
minimum height = 2em,
minimum width = 4em
}
}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\node[signal] (input) {};
\node[
block,
right = of input
] (block 1) {};
\node[
block,
right = of block 1
] (block 2) {};
\node[
signal,
right = of block 2
] (output) {};
\draw
[->] (input) -- (block 1);
\draw
[->] (block 1) -- (block 2);
\draw
[->] (block 2) -- (output);
\end{tikzpicture}
\end{document}
给出:
我希望(线条和箭头不应该加粗):
是否可以或多或少地自动完成此操作,而无需手动绘制三条线。甚至三条线的位置也应自动设置。这意味着:中线应位于垂直中间。上下线应对称地位于中线的上方和下方。
提前感谢您的帮助和努力!
答案1
你可以利用\foreach
循环
\documentclass{scrartcl}
\usepackage{tikz}
\tikzset{
signal/.style = coordinate,
block/.style = {
draw,
rectangle,
minimum height = 2em,
minimum width = 4em
}
}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
\node[signal] (input) {};
\node[
block,
right = of input
] (block 1) {};
\node[
block,
right = of block 1
] (block 2) {};
\node[
signal,
right = of block 2
] (output) {};
\draw
[->] (input) -- (block 1);
\foreach \k in {-1,0,1}{
\draw [->] ([yshift=\k*.2cm]block 1.east) -- ([yshift=\k*.2cm]block 2.west);
\draw [->] ([yshift=\k*.2cm]block 2.east) -- ([yshift=\k*.2cm]output.west);
}
\end{tikzpicture}
\end{document}
我根据\k
(-1
、、0
以及最终1
)的值将箭头的位置上下移动一定量。
答案2
像这样吗?
\documentclass{scrartcl}
\usepackage{tikz}
\tikzset{
signal/.style = coordinate,
block/.style = {
draw,
rectangle,
minimum height = 2em,
minimum width = 4em
}
}
\usetikzlibrary{decorations.markings,positioning}
\tikzset{triple line with arrows/.style args={#1,#2,#3}{decorate,decoration={markings,%
mark=at position 0 with {\coordinate (ta-base-1) at (0,4pt);
\coordinate (ta-base-2) at (0,0pt);
\coordinate (ta-base-3) at (0,-4pt);},
mark=at position 1 with {\draw[#1] (ta-base-1) -- (0,4pt);
\draw[#2] (ta-base-2) -- (0,0pt);
\draw[#3] (ta-base-3) -- (0,-4pt);}}}}
\begin{document}
\begin{tikzpicture}
\node[signal] (input) {};
\node[
block,
right = of input
] (block 1) {};
\node[
block,
right = of block 1
] (block 2) {};
\node[
signal,
right = of block 2
] (output) {};
\draw
[->] (input) -- (block 1);
\draw
[triple line with arrows={->,->,->}] (block 1) -- (block 2);
\draw
[triple line with arrows={->,->,->}] (block 2) -- (output);
\end{tikzpicture}
\end{document}
附录:只是为了好玩:一个稍微更灵活的版本。
\documentclass{scrartcl}
\usepackage{tikz}
\tikzset{
signal/.style = coordinate,
block/.style = {
draw,
rectangle,
minimum height = 2em,
minimum width = 4em
}
}
\usetikzlibrary{decorations.markings,positioning}
\pgfkeys{tikz/.cd,
triple line distance/.store in =\triplelinedist,
triple line distance=4pt
}
\tikzset{triple line with arrows/.style args={#1,#2,#3}{decorate,decoration={markings,%
mark=at position 0 with {\coordinate (ta-base-1) at (0,\triplelinedist);
\coordinate (ta-base-2) at (0,0pt);
\coordinate (ta-base-3) at (0,-\triplelinedist);},
mark=at position 1 with {\draw[#1] (ta-base-1) -- (0,\triplelinedist);
\draw[#2] (ta-base-2) -- (0,0pt);
\draw[#3] (ta-base-3) -- (0,-\triplelinedist);}}}}
\begin{document}
\begin{tikzpicture}
\node[signal] (input) {};
\node[
block,
right = of input
] (block 1) {};
\node[
block,
right = of block 1
] (block 2) {};
\node[
signal,
right = of block 2
] (output) {};
\draw
[->] (input) -- (block 1);
\draw
[triple line with arrows={->,->,->}] (block 1) -- (block 2);
\draw
[triple line with arrows={->,->,->},triple line distance=5pt] (block 2) -- (output);
\end{tikzpicture}
\end{document}
答案3
厚颜无耻地引用我自己的答案这里(针对此情况略作调整)。
我定义了一个新形状block
,它有三个选项可以赋予样式block={inputs=<inputs>,outputs=<outputs>,io spacing=<length>}
:
inputs
任意整数输入,默认为 1outputs
任意整数输出数,默认为 1io spacing
输入和输出之间的间距,默认为 5mm
利用这种形状/样式我们可以绘制:
仅使用(也使用positioning
库,参见底部的 MWE):
\begin{tikzpicture}
\node[block={outputs=3}](node1){};
\node[block={inputs=3,outputs=3},right=of node1](node2){};
\draw[<-] (node1.input 1) -- ++(-1,0);
\foreach \i in {1,...,3}{
\draw[->] (node1.output \i) -- (node2.input \i);
\draw[->] (node2.output \i) --++(1,0);
}
\end{tikzpicture}
对于您的问题来说,这可能有点小题大做,但是谁知道呢,您可能还有一些额外的需求可以通过这个来满足:)
完整的形状定义是:
\makeatletter
\newdimen\block@iospacing
\newdimen\block@height
\newif\if@block@flip
\tikzset{
block/.code={
\pgfkeys{
/block/.cd,
#1
}
\pgfmathsetlengthmacro{\block@height}{%
max(10mm, int(max(\block@inputs,\block@outputs) * \block@iospacing))}
\tikzset{
draw,
align=center,
minimum width = 15mm,
minimum height = \block@height,
shape=block
}
}
}
\pgfkeys{
/block/.is family,
/block/.cd,
inputs/.code={
\pgfmathparse{int(#1)}
\let\block@inputs=\pgfmathresult
},
inputs=1,
outputs/.code={
\pgfmathparse{int(#1)}
\let\block@outputs=\pgfmathresult
},
outputs=1,
io spacing/.code=\setlength\block@iospacing{#1},
io spacing=5mm,
flip/.is choice,
flip/true/.code={\@block@fliptrue\def\@block@flipbool{1}},
flip/false/.code={\@block@flipfalse\def\@block@flipbool{0}},
flip/.default=true,
flip=false,
}
\pgfdeclareshape{block}{
\inheritsavedanchors[from={rectangle}]
\savedanchor\centerpoint{%
\pgf@x=.5\wd\pgfnodeparttextbox%
\pgf@y=.5\ht\pgfnodeparttextbox%
\advance\pgf@y by-.5\dp\pgfnodeparttextbox%
}
\inheritsavedanchors[from=rectangle]
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{north west}
\inheritanchor[from=rectangle]{north east}
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{text}
\inheritanchor[from=rectangle]{west}
\inheritanchor[from=rectangle]{east}
\inheritanchor[from=rectangle]{mid}
\inheritanchor[from=rectangle]{mid west}
\inheritanchor[from=rectangle]{mid east}
\inheritanchor[from=rectangle]{base}
\inheritanchor[from=rectangle]{base west}
\inheritanchor[from=rectangle]{base east}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{south west}
\inheritanchor[from=rectangle]{south east}
\savedmacro\blockinputs{%
\pgfmathparse{int(\block@inputs)}%
\let\blockinputs=\pgfmathresult}%
\savedmacro\blockoutputs{%
\pgfmathparse{int(\block@outputs)}%
\let\blockoutputs=\pgfmathresult}%
\savedmacro\blockmaxio{%
\pgfmathparse{int(max(\block@inputs,\block@outputs))}%
\let\blockmaxio=\pgfmathresult}%
\savedmacro\blockflip{%
\pgfmathparse{\@block@flipbool}%
\let\blockflip=\pgfmathresult}%
\saveddimen\halfwidth{\pgfmathsetlength\pgf@x{%
\pgfkeysvalueof{/pgf/minimum width}/2}\pgfmathresult}
\saveddimen\halfheight{\pgfmathsetlength\pgf@x{%
\pgfkeysvalueof{/pgf/minimum height}/2}\pgfmathresult}
\saveddimen\iospacing{\pgfmathsetlength\pgf@x{%
\block@iospacing}\pgfmathresult}
\inheritbackgroundpath[from={rectangle}]
\pgfutil@g@addto@macro\pgf@sh@s@block{%
\pgfmathloop%
\ifnum\pgfmathcounter>\blockinputs\relax%
\else%
\pgfutil@ifundefined{pgf@anchor@block@input \pgfmathcounter}{%
\expandafter\xdef\csname pgf@anchor@block@input %
\pgfmathcounter\endcsname{\noexpand%
\pgf@sh@lib@block@in@anchor{\pgfmathcounter}%
}%
}{}
\repeatpgfmathloop%
\pgfmathloop%
\ifnum\pgfmathcounter>\blockoutputs\relax%
\else%
\pgfutil@ifundefined{pgf@anchor@block@output \pgfmathcounter}{%
\expandafter\xdef\csname pgf@anchor@block@output %
\pgfmathcounter\endcsname{\noexpand%
\pgf@sh@lib@block@out@anchor{\pgfmathcounter}%
}%
}{}
\repeatpgfmathloop%
}%
}
\def\pgf@sh@lib@block@in@anchor#1{%
\pgf@process{\centerpoint}%
\pgf@ya=\pgf@y%
\ifnum\blockflip=0\relax%
\pgf@process{\southwest}%
\else%
\pgf@process{\northeast}%
\fi%
\pgfmathsetlength\pgf@y{\pgf@ya + (0.5*(\blockinputs+1)-#1)*\iospacing}
}
\def\pgf@sh@lib@block@out@anchor#1{%
\pgf@process{\centerpoint}%
\pgf@ya=\pgf@y%
\ifnum\blockflip=0\relax%
\pgf@process{\northeast}%
\else%
\pgf@process{\southwest}%
\fi%
\pgfmathsetlength\pgf@y{\pgf@ya + (0.5*(\blockoutputs+1)-#1)*\iospacing}
}
\makeatother
MWE(copy-past
能够):
\documentclass[tikz,margin=2mm]{standalone}
\usetikzlibrary{positioning}
\makeatletter
\newdimen\block@iospacing
\newdimen\block@height
\newif\if@block@flip
\tikzset{
block/.code={
\pgfkeys{
/block/.cd,
#1
}
\pgfmathsetlengthmacro{\block@height}{%
max(10mm, int(max(\block@inputs,\block@outputs) * \block@iospacing))}
\tikzset{
draw,
align=center,
minimum width = 15mm,
minimum height = \block@height,
shape=block
}
}
}
\pgfkeys{
/block/.is family,
/block/.cd,
inputs/.code={
\pgfmathparse{int(#1)}
\let\block@inputs=\pgfmathresult
},
inputs=1,
outputs/.code={
\pgfmathparse{int(#1)}
\let\block@outputs=\pgfmathresult
},
outputs=1,
io spacing/.code=\setlength\block@iospacing{#1},
io spacing=5mm,
flip/.is choice,
flip/true/.code={\@block@fliptrue\def\@block@flipbool{1}},
flip/false/.code={\@block@flipfalse\def\@block@flipbool{0}},
flip/.default=true,
flip=false,
}
\pgfdeclareshape{block}{
\inheritsavedanchors[from={rectangle}]
\savedanchor\centerpoint{%
\pgf@x=.5\wd\pgfnodeparttextbox%
\pgf@y=.5\ht\pgfnodeparttextbox%
\advance\pgf@y by-.5\dp\pgfnodeparttextbox%
}
\inheritsavedanchors[from=rectangle]
\inheritanchorborder[from=rectangle]
\inheritanchor[from=rectangle]{north}
\inheritanchor[from=rectangle]{north west}
\inheritanchor[from=rectangle]{north east}
\inheritanchor[from=rectangle]{center}
\inheritanchor[from=rectangle]{text}
\inheritanchor[from=rectangle]{west}
\inheritanchor[from=rectangle]{east}
\inheritanchor[from=rectangle]{mid}
\inheritanchor[from=rectangle]{mid west}
\inheritanchor[from=rectangle]{mid east}
\inheritanchor[from=rectangle]{base}
\inheritanchor[from=rectangle]{base west}
\inheritanchor[from=rectangle]{base east}
\inheritanchor[from=rectangle]{south}
\inheritanchor[from=rectangle]{south west}
\inheritanchor[from=rectangle]{south east}
\savedmacro\blockinputs{%
\pgfmathparse{int(\block@inputs)}%
\let\blockinputs=\pgfmathresult}%
\savedmacro\blockoutputs{%
\pgfmathparse{int(\block@outputs)}%
\let\blockoutputs=\pgfmathresult}%
\savedmacro\blockmaxio{%
\pgfmathparse{int(max(\block@inputs,\block@outputs))}%
\let\blockmaxio=\pgfmathresult}%
\savedmacro\blockflip{%
\pgfmathparse{\@block@flipbool}%
\let\blockflip=\pgfmathresult}%
\saveddimen\halfwidth{\pgfmathsetlength\pgf@x{%
\pgfkeysvalueof{/pgf/minimum width}/2}\pgfmathresult}
\saveddimen\halfheight{\pgfmathsetlength\pgf@x{%
\pgfkeysvalueof{/pgf/minimum height}/2}\pgfmathresult}
\saveddimen\iospacing{\pgfmathsetlength\pgf@x{%
\block@iospacing}\pgfmathresult}
\inheritbackgroundpath[from={rectangle}]
\pgfutil@g@addto@macro\pgf@sh@s@block{%
\pgfmathloop%
\ifnum\pgfmathcounter>\blockinputs\relax%
\else%
\pgfutil@ifundefined{pgf@anchor@block@input \pgfmathcounter}{%
\expandafter\xdef\csname pgf@anchor@block@input %
\pgfmathcounter\endcsname{\noexpand%
\pgf@sh@lib@block@in@anchor{\pgfmathcounter}%
}%
}{}
\repeatpgfmathloop%
\pgfmathloop%
\ifnum\pgfmathcounter>\blockoutputs\relax%
\else%
\pgfutil@ifundefined{pgf@anchor@block@output \pgfmathcounter}{%
\expandafter\xdef\csname pgf@anchor@block@output %
\pgfmathcounter\endcsname{\noexpand%
\pgf@sh@lib@block@out@anchor{\pgfmathcounter}%
}%
}{}
\repeatpgfmathloop%
}%
}
\def\pgf@sh@lib@block@in@anchor#1{%
\pgf@process{\centerpoint}%
\pgf@ya=\pgf@y%
\ifnum\blockflip=0\relax%
\pgf@process{\southwest}%
\else%
\pgf@process{\northeast}%
\fi%
\pgfmathsetlength\pgf@y{\pgf@ya + (0.5*(\blockinputs+1)-#1)*\iospacing}
}
\def\pgf@sh@lib@block@out@anchor#1{%
\pgf@process{\centerpoint}%
\pgf@ya=\pgf@y%
\ifnum\blockflip=0\relax%
\pgf@process{\northeast}%
\else%
\pgf@process{\southwest}%
\fi%
\pgfmathsetlength\pgf@y{\pgf@ya + (0.5*(\blockoutputs+1)-#1)*\iospacing}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node[block={outputs=3}](node1){};
\node[block={inputs=3,outputs=3},right=of node1](node2){};
\draw[<-] (node1.input 1) -- ++(-1,0);
\foreach \i in {1,...,3}{
\draw[->] (node1.output \i) -- (node2.input \i);
\draw[->] (node2.output \i) --++(1,0);
}
\end{tikzpicture}
\end{document}