![如何绘制块图(多个完整子图连接在一起)](https://linux22.com/image/470082/%E5%A6%82%E4%BD%95%E7%BB%98%E5%88%B6%E5%9D%97%E5%9B%BE%EF%BC%88%E5%A4%9A%E4%B8%AA%E5%AE%8C%E6%95%B4%E5%AD%90%E5%9B%BE%E8%BF%9E%E6%8E%A5%E5%9C%A8%E4%B8%80%E8%B5%B7%EF%BC%89.png)
我想画一个块图。块图(或团树)是一种图,其中每个双连通分量(块)都是一个团。团是图中顶点(节点)的子集,其中团中的每两个不同顶点(节点)都是相邻的。基本上,块图是许多完整的子图($K_n$)连接在一起。
我附上了我想要绘制的块图的草图。它由 $K_7$、$K_5$、$K_4$、$K_1$ 和两个 $K_3$ 组成。
我在这个论坛上找到了一些代码,可以得到 $K_7$、$K_5$ 和 $K_3$。但是,它并没有完全解决问题。我只希望团共享一个顶点,并且希望它们在不同的位置旋转(如图所示)。
此外,LateX 代码中的顶点(节点)太大,即使我改变半径的大小,似乎也无法使它们变小。
这是我的 MWE:
\documentclass{article}
\usepackage{ifthen}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric, positioning, calc}
\tikzset{%
mynode/.style={%
circle, radius=2pt, draw=darkgray, fill=white
}
}
\begin{document}
\begin{tikzpicture}
\node[minimum size=4cm, regular polygon, regular polygon sides=7, rotate=180] (epta) {};
\foreach \x in {1,2,...,7}{%
\node[mynode] at (epta.corner \x) (e\x) {};
}
\foreach \x in {1,2,...,7}{%
\foreach \y in {1,2,...,7}{%
\ifthenelse{\x>\y}{}{\draw[darkgray] (e\x) -- (e\y);}
}}
\node[below= 2pt of e1] {};
\node[below= 2pt of e2] {};
\node[above right = 2pt and -1pt of e3] {};
\node[above right = 0pt and -1pt of e4] {};
\node[above left = 0pt and -1pt of e5] {};
\node[below left = 0pt and -1pt of e6] {};
\node[below left = 0pt and -1pt of e7] {};
\node(p1) at (e2) {};
\node(p2) at (e3) {};
\foreach \nextp/\prevp/\i in {p3/p2/1,p4/p3/2,p5/p4/3}{%
\node[mynode] (\nextp) at ($(\prevp)+(77-\i*72:50pt)$) {};
}
\foreach \x in {1,2,...,5}{%
\foreach \y in {1,2,...,5}{%
\ifthenelse{\x>\y}{}{\draw[darkgray] (p\x) -- (p\y);}
}}
\node[mynode, below right = 40pt and 1pt of e2, label={[label distance=2pt]-90:}] (s1) {};
\draw[darkgray] (e1) -- (p5) -- (s1) -- (e1);
\end{tikzpicture}
\end{document}
目前结果:
任何帮助将不胜感激!
答案1
考虑到该库的强大功能(参见 Qrrbrbirlbel 的解决方案),这可能有点重新发明轮子graphs
,但这是一个自己动手的可能性。
该命令\complete[<prefix>]{<num nodes>}{<start coordinate>}{<radius of circle>}{<direction toward center>}
将执行您想要的操作。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\tikzset{
vertex/.style={draw, thick, circle, minimum size=3mm, inner sep=0pt}
}
\newcommand{\complete}[5][]{
\foreach \k in {1,...,#2} \node[vertex](#1\k) at ($([shift=(#5:#4)]#3)+({360/#2*(\k-1)+180+#5}:#4)$){};
\foreach \k in {1,...,#2} \foreach \j in {1,...,\k} \draw(#1\k)--(#1\j);
} % #1=node label prefix, #2=n vertices, #3=start coordinate, #4=radius, optional #5=angle toward center
\begin{document}
\begin{tikzpicture}
\complete[N]{7}{0,0}{2cm}{0}
\complete[M]{5}{N5}{1.5cm}{30}
\complete[P]{3}{M3}{1cm}{0}
\complete[Q]{3}{M2}{1cm}{-90}
\complete[R]{2}{Q3}{.5cm}{0}
\complete[S]{4}{R2}{1cm}{0}
\end{tikzpicture}
\end{document}
答案2
graphs
/库graphs.standard
已经带来了subgraph K_n
它会自动将所有节点相互连接。
随着counterclockwise
钥匙我们将激活circular placement
将节点放置在圆上的策略。它使用radius
钥匙和phase
钥匙将n
节点放置在圆圈上。
然后该习俗joined subgraph K_n
可以用来“加入”另一个n与节点形成join in
一个圆圈的节点n+1 个节点。
密钥position
决定了该节点在这个新子图中的位置join in
。位置0
代表阶段 0,位置 1 代表位置 之后的下一个节点0
。它基本上是一个phase
转换为节点位置的值。我希望这可以减少用户所需的计算,但它也有点晦涩难懂……
请注意,的值n
仅指定新的新子图中的节点数而不是包括该节点在内的总数join in
。
该graphs
库仅提供了用于放置和连接节点的新的、更短的语法。它不提供任何无法通过\node
s 和edge
s 实现的功能。
代码
\documentclass[tikz]{standalone}
\usetikzlibrary{graphs.standard}
\newcommand*\tg[1]{\pgfkeysvalueof{/tikz/graphs/#1}}
\tikzgraphsset{
show my name/.style={
label={[node font=\tiny, inner sep=+0pt, magenta]\tikzgraphnodefullname}},
join in/.initial=, position/.initial=0,
declare={joined subgraph K_n}{
[
/utils/exec=%
\pgfmathtruncatemacro\tgN{\tikzgraphVnum+1}%
\pgfmathsetmacro\tgPhase{(\tg{position})*360/\tgN},
/tikz/shift/.expanded={(\tg{join in})},
/tikz/shift/.expanded={(\tgPhase:{-(\tg{radius})})},
] (\tg{join in}) --
subgraph K_n[counterclockwise=\tgN, phase=\tgPhase+360/\tgN]}}
\begin{document}
\tikz[
vertex/.style={
shape=circle, draw,
inner sep=+0pt, minimum size=+3pt}, % radius is not a shape key
thick,
]
\graph[
empty nodes, % no text in nodes
nodes=vertex, % all nodes be of style vertex
radius=1cm, % base radius (also default)
nodes=show my name, % debug the names
] {
% for the heptagraph we're using the built-in subgraph:
% n = 7 → seven nodes
% counterclockwise → arranged in a circle
% phase = -90 → the first one is at -90
% this uses the radius = 1cm value to place the nodes on a circle
% they are named “seven 1”, “seven 2”, …
subgraph K_n[name=seven, n=7, counterclockwise, phase=-90],
% the next one is already a custom joined subgraph K_n
% which always create a counterclockwise addition
% where one of the nodes in that circle is already occupied by
% “join in” at the “position” where position
% is counted from angle 0° → position = 0
% the “n” value here is the number of additions without the “join in” node
joined subgraph K_n[name=five, n=4, join in=seven 3, position=3],
{[radius=.75cm]
joined subgraph K_n[name=threeA, n=2, join in=five 2, position=1.5 ],
joined subgraph K_n[name=threeB, n=2, join in=five 1, position=0.75],
joined subgraph K_n[name=two, n=1, join in=threeB 2, position=1 , radius=.5cm],
joined subgraph K_n[name=four, n=3, join in=two 1, position=2 ]
}
};
\end{document}