我正在寻找一种在 Tikz 中绘制有向超图的简单方法,其中超边是顶点集的有序对。例如,我希望超边 ({a,b},{c}) 和 ({c},{a,b}) 呈现如下:
“入”顶点(左侧)应垂直对齐,“出”顶点(右侧)也应垂直对齐。就我的目的而言,入顶点或出顶点的数量绝不会超过两个,我很乐意将此融入解决方案中。解决方案应足够灵活,以适应大于此处显示的单个字符的节点标签。
我还希望能够将它们组装成更大的超图,如下所示,在这种情况下超边的臂不需要具有相同的长度:
尽管“方向”始终是从左到右读取的。我并不关心线条重叠(我只会处理简单的图形,并且可以安排事物以使线条不重叠)。
出于美观的原因,应该很容易移动节点,例如下面是上面的图表,但布局略有不同:
标题这个问题类似,但我的要求略有不同。
答案1
第二次尝试,这次对布局做了一些假设。我假设您希望超边始终与三元组的“孤独”节点对齐(例如和c
中)。({a,b},{c})
({c},{a,b})
由于您似乎需要对节点的定位进行精细控制,我建议如下:首先,您放置命名节点并进行手动定位(使用您喜欢的任何方法,从绝对坐标到相对定位);然后指定超边并创建相应的弧。以下是可以帮助您完成第二步的宏:
\newcommand{\hyperedge}[4][180]{
\draw (#2.#1) ++(#1:.5) edge (#2) edge (#3) edge (#4);
}
它需要 4 个参数(第一个是可选的):\hyperedge[angle]{c}{a}{b}
假设它c
是孤独的节点,并要求您指定超边应伸出它的角度。
宏的定义是这样工作的:移动到孤独节点的右/左边界(这是通过将移动到角度为(#2.#1)
的节点边界来实现的),然后向右/向左移动,这是边缘“中心”的坐标;然后使用动作将此“中心”与节点连接起来。#2
#1
.5
edge
这是使用 tikz 和我的宏的第二个示例:
\documentclass{standalone}
\usepackage{tikz}
\newcommand{\hyperedge}[4][180]{
\draw (#2.#1) ++(#1:.5) edge (#2) edge (#3) edge (#4);
}
\begin{document}
\begin{tikzpicture}[
y=.7cm, x=1cm,
every edge/.append style={thick}
]
\node (a) at (-1,1) {a};
\node (b) at (-1,-1) {b};
\node (c) at (0,0) {c};
\node (d) at (1,1) {d};
\node (e) at (1,-1) {e};
\node (g) at (2,-2) {g};
\hyperedge{c}{b}{a}
\hyperedge[0]{c}{d}{e}
\hyperedge{g}{b}{e}
\end{tikzpicture}
\end{document}
其具有较高的可读性并且易于扩展。
您可以通过使用其他方式指定角度(其他派生的宏)或使用自定义样式来丰富它来详细说明这一点。
超边“中心”的另一种放置方式是重心坐标:
\newcommand{\hyperedge}[3]{
\draw (barycentric cs:#1=1,#2=1,#3=1) edge (#1) edge (#2) edge (#3);
}
请注意,这并不需要参数angle
。
答案2
这个简单的例子应该可以帮助你入门
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[
every edge/.append style={thick}
]
\coordinate (e1) at (0,0);
\path (e1) (130:1) node[circle] (a) {a};
\path (e1) (230:1) node[circle] (b) {b};
\path (e1) (0:.8) node[circle] (c) {c};
\draw (e1) edge (a) edge (b) edge (c);
\end{tikzpicture}
\end{document}
在这里我选择先定位超边(e1)
,然后通过使用移动到边的坐标来定位相对于它\path
的节点(e1)
,而不是从那里移动到某处并放置节点。坐标(angle:radius)
是极坐标,而坐标(x,y)
是笛卡尔坐标。
超边的实际“分支”是由使用以第一个节点为起点并将所有其他节点连接到该节点的操作的\draw
命令绘制的。edge
使用这些构建块添加图表的其他部分应该很容易。由于您似乎希望对节点/边的定位进行相当精确的控制,因此我不会尝试任何更通用/自动化的操作。