我无法完全做到这一点,因为单独定位每个节点非常耗时。我认为可能有一些聪明的方法来完成同样的工作。请参阅下面的代码-
\documentclass[tikz,border=2pt]{standalone}
\usetikzlibrary{shapes.geometric, arrows}
\tikzset{
box/.style = {draw, rectangle, rounded corners, minimum width=1.1cm, minimum height=4cm},
cir/.style = {draw, circle, minimum width=0.5cm, text centered},
arr/.style = {-}
}
\begin{document}
\begin{tikzpicture}
\node (box11) [box] {};
\node (cir11) [cir,below of=box11,yshift=+2cm] {O$_1$};
\node (cir12) [cir,below of=cir11,yshift=-1cm] {O$_k$};
\node (box21) [box,right of=box11,xshift=+2cm] {};
\node (cir21) [cir,below of=box21,yshift=+2cm] {h$_1$};
\node (cir22) [cir,below of=cir21,yshift=-1cm] {h$_n$};
\node (box31) [box,right of=box21,xshift=+2cm] {};
\node (cir31) [cir,below of=box31,yshift=+2cm] {h$_1$};
\node (cir32) [cir,below of=cir31,yshift=-1cm] {h$_n$};
\node (box41) [box,right of=box31,xshift=+2cm] {};
\node (cir41) [cir,below of=box41,yshift=+2cm] {u$_1$};
\node (cir42) [cir,below of=cir41,yshift=-1cm] {u$_m$};
\draw [arr] (box11) -- (box21);
\draw [arr] (box21) -- (box31);
\draw [arr] (box31) -- (box41);
\end{tikzpicture}
\end{document}
请帮忙。
答案1
要制作点,可以通过 轻松管理decorations
,特别是decorations.markings
。我制作了一种装饰路径的样式,如下所示。您当前定位所有内容的方式是实用的,但您可以(应该)使用库positioning
,因为它使代码更简洁,更容易理解。您还可以使用宏来定义常见尺寸(例如方框分隔和圆形分隔……)。
我相信你遇到的困难是一堆相互连接的线条,Ti 中有一些例子钾Z 手册下指定图表看起来像那个图,这样就可以使用这个功能了。我在这里假设线条是(或可能)均匀分布的(在垂直方向上),尽管所呈现的图形看起来并不均匀。为此,我利用了操作let
来计算和的大小branch
。如果它们是grow
\graph
不是应该均匀分布,而不是手动指定,但是可通过语句自动连接\foreach
。
\documentclass[tikz,border=2pt]{standalone}
\usetikzlibrary{shapes.geometric, arrows, graphs, graphs.standard, positioning, decorations.markings, calc}
\tikzset{
box/.style = {draw, rectangle, rounded corners, minimum width=1.1cm, minimum height=4cm, outer sep=2mm},
cir/.style = {draw, circle, minimum size=.75cm, align=center, outer sep=2mm, inner sep=0.2em},
arr/.style = {-},
shorten/.style = {shorten <=#1, shorten >=#1},
dots/.style= {decoration={markings, mark= between positions 0 and 1 step 2mm with {\fill circle (0.75mm);}},decorate}
}
\begin{document}
\begin{tikzpicture}
\def\circlesep{2mm}
\def\boxsep{2cm}
\node (box11) [box] {};
\node (cir11) [cir,below=\circlesep] at (box11.north) {O$_1$};
\node (cir12) [cir,above=\circlesep] at (box11.south) {O$_k$};
\draw[dots] (cir11) -- (cir12);
\node (box21) [box,right=\boxsep of box11] {};
\node (cir21) [cir,below=\circlesep] at (box21.north) {h$_1$};
\node (cir22) [cir,above=\circlesep] at (box21.south) {h$_n$};
\draw[dots] (cir21) -- (cir22);
\node (box31) [box,right=\boxsep of box21] {};
\node (cir31) [cir,below=\circlesep] at (box31.north) {h$_1$};
\node (cir32) [cir,above=\circlesep] at (box31.south) {h$_n$};
\draw[dots] (cir31) -- (cir32);
\node (box41) [box,right=\boxsep of box31] {};
\node (cir41) [cir,below=\circlesep] at (box41.north) {u$_1$};
\node (cir42) [cir,above=\circlesep] at (box41.south) {u$_m$};
\draw[dots] (cir41) -- (cir42);
\draw[dots] (cir21.east -| box21.east) -- (cir31.west -| box31.west);
\draw[dots] (box21.east) -- (box31.west);
\draw[dots] (cir22.east -| box21.east) -- (cir32.west -| box31.west);
\path[shift={([xshift=.4cm]cir11.east)}] let \p1=($([xshift=.4cm]cir11.east)$), \p2=($([xshift=-.4cm]cir22.west)$),
\n1={\x2-\x1}, \n2={(\y1-\y2)/3} in graph[nodes={coordinate},
empty nodes,
grow right=\n1,
branch down=\n2]{subgraph K_nm [n=4, m=4]};
\path[shift={([xshift=.4cm]cir31.east)}] let \p1=($([xshift=.4cm]cir31.east)$), \p2=($([xshift=-.4cm]cir42.west)$),
\n1={\x2-\x1}, \n2={(\y1-\y2)/3} in graph[nodes={coordinate},
empty nodes,
grow right=\n1,
branch down=\n2]{subgraph K_nm [n=4, m=4]};
\end{tikzpicture}
\end{document}
另一个值得注意的事情是,虽然你已经minimum width
为cir
节点指定了,但大多数节点都超出了这个最小宽度(看看节点u_1
,它肯定比其他节点小),这使得所有框的点都不同,我修改了节点inner sep
以cir
使它们符合minimum width
答案2
您可以使用pics
绘制图表的“通用组件”,然后将这些图片放在您想要的位置。它们pics
还可以接受参数,因此您可以将所需的不同标签传递给它们。这样做的最大优点是您只需调整每个组件中的绘图即可。
这样做我得到:
以下是代码:
\documentclass{article}
\usepackage{tikz}
\tikzset{% define a pic for the blocks, with the labels as arguments
circnode/.style={circle, draw, minimum size=6mm, inner sep=0mm},
pics/myblock/.style args={#1,#2}{
code={\draw[thick,rounded corners](0,0) rectangle (1,4);
\node at (0.5, 3.6) [circnode] {$#1_1$};
\node at (0.5, 0.4) [circnode] {$#1_#2$};
\foreach \y in {0.95,1.25,...,3.35} {
\filldraw (0.5,\y) circle (1mm);
}
}
},
% and another pic for the bipartite graph
pics/snare/.style = {
code = { \foreach \y/\A in {0.4/A, 1.2/B, 2.8/C, 3.6/D} {
\coordinate (0\A) at (0,\y);
\coordinate (1\A) at (1,\y);
}
\draw(0A)--(1A)--(0B)--(1B)--(0C)--(1C)--(0D)--(1D)--(0B)
--(1C)--(0A)--(1D)--(0C)--(1A)--(0D)--(1D)--(0A)
--(1B);
}
}
}
\begin{document}
\begin{tikzpicture}
\draw (0,0) pic{myblock={o,k}};
\draw (1.5,0) pic{snare};
\draw (3,0) pic{myblock={h,n}};
\foreach \x in {4.3,4.6,...,6.9} {
\foreach \y in {0.4, 2.2, 3.6} {
\filldraw (\x,\y) circle (1mm);
}
}
\draw (7,0) pic{myblock={o,k}};
\draw (8.5,0) pic{snare};
\draw (10,0) pic{myblock={u,m}};
\end{tikzpicture}
\end{document}