我有这张照片:
生成者:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc, shapes, positioning}
\begin{document}
\begin{tikzpicture}
\node (A) [draw, ellipse, minimum width=3cm, minimum height=6cm] at (0,0) {};
\foreach \i in {0,...,3} {
\node (A\i) [draw, circle, yshift=-0.5cm, outer sep=0.3cm] at ($(A.north)!\i/5!(A.south)$) {\i};
}
\node (B) [draw, ellipse, minimum width=3cm, minimum height=6cm] at (6,0) {};
\foreach \i in {0,...,3} {
\node (B\i) [draw, circle, yshift=-0.5cm, outer sep=0.3cm] at ($(B.north)!\i/5!(B.south)$) {\i};
}
\draw[rounded corners=0.5cm, thick, red] (A0.north west)--(B0.north east)--(B0.south east)--(A0.south west)--cycle;
\draw[rounded corners=0.5cm, thick, red] (A0.north west)--(B2.north east)--(B2.south east)--(A0.south west)--cycle;
\draw[rounded corners=0.5cm, thick, green] (A1.north west)--(B1.north east)--(B1.south east)--(A1.south west)--cycle;
\draw[rounded corners=0.5cm, thick, green] (A1.north west)--(B3.north east)--(B3.south east)--(A1.south west)--cycle;
\draw[rounded corners=0.5cm, thick, blue] (A3.north west)--(B1.north east)--(B1.south east)--(A3.south west)--cycle;
\end{tikzpicture}
\end{document}
显然,这些线在节点周围并不是很好走。我尝试使用(东南)-(西南)控制点来引导它们,但效果仍然不太好。
我怎样才能使线条在圆圈周围流畅地流动?
谢谢!
答案1
north
、west
等指的是节点的绝对方向,而不是相对于您在指定节点之间绘制的线的方向。此外,您的圆的半径太大,因此即使对于第一个(水平)连接,圆的结果也不太好。您可能还想创建一个 tikz 样式来自动绘制这些连接的过程。
calc
这是一个使用库、to path
tikz 样式和(与您的初始方法一致)的解决方案rounded corners
。该解决方案本质上是在两个指定节点周围创建 4 个控制节点来绘制一个矩形,然后将其角圆化。圆化也可以修改或删除,如下例所示。tikz 样式的输入是矩形宽度的一半,默认情况下我设置为该宽度4mm
(这也是默认的圆角半径)。
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc, shapes, positioning}
\tikzset{connect/.style={rounded corners=#1,
to path= ($(\tikztostart)!-#1!(\tikztotarget)!-#1!-90:(\tikztotarget)$) -- ($(\tikztotarget)!-#1!(\tikztostart)!-#1!90:(\tikztostart)$) --
($(\tikztotarget)!-#1!(\tikztostart)!#1!90:(\tikztostart)$) -- ($(\tikztostart)!-#1!(\tikztotarget)!-#1!90:(\tikztotarget)$) -- cycle (\tikztotarget)
}}
\tikzset{connect/.default=4mm}
\begin{document}
\begin{tikzpicture}
\node (A) [draw, ellipse, minimum width=3cm, minimum height=6cm] at (0,0) {};
\foreach \i in {0,...,3} {
\node (A\i) [draw, circle, yshift=-0.5cm, outer sep=0.3cm] at ($(A.north)!\i/5!(A.south)$) {\i};
}
\node (B) [draw, ellipse, minimum width=3cm, minimum height=6cm] at (6,0) {};
\foreach \i in {0,...,3} {
\node (B\i) [draw, circle, yshift=-0.5cm, outer sep=0.3cm] at ($(B.north)!\i/5!(B.south)$) {\i};
}
\draw (A0) to[connect] (B0); % default
\draw[green] (A1) to[connect=6mm] (B1); % coloured, different size
\draw[red,dashed,ultra thick] (A1) to[connect] (B3); % coloured,dashed,thick, etc...
\draw[blue] (A3) to[connect,rounded corners=2mm] (B2); % different round
\draw[blue] (A2) to[connect,sharp corners] (B3); % or sharp
\draw[lightgray] (B1) to[connect] (A2) to[connect] (B2); % multiple at once
\end{tikzpicture}
\end{document}
答案2
您可以利用这个很棒的答案经过杰克这可能有点像用大锤砸核桃,但它确实有效。
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc, shapes, positioning}
% command by Jake https://tex.stackexchange.com/a/27185/124577
\newcommand{\convexpath}[2]{
[
create hullnodes/.code={
\global\edef\namelist{#1}
\foreach [count=\counter] \nodename in \namelist {
\global\edef\numberofnodes{\counter}
\node at (\nodename) [draw=none,name=hullnode\counter] {};
}
\node at (hullnode\numberofnodes) [name=hullnode0,draw=none] {};
\pgfmathtruncatemacro\lastnumber{\numberofnodes+1}
\node at (hullnode1) [name=hullnode\lastnumber,draw=none] {};
},
create hullnodes
]
($(hullnode1)!#2!-90:(hullnode0)$)
\foreach [
evaluate=\currentnode as \previousnode using \currentnode-1,
evaluate=\currentnode as \nextnode using \currentnode+1
] \currentnode in {1,...,\numberofnodes} {
-- ($(hullnode\currentnode)!#2!-90:(hullnode\previousnode)$)
let \p1 = ($(hullnode\currentnode)!#2!-90:(hullnode\previousnode) - (hullnode\currentnode)$),
\n1 = {atan2(\y1,\x1)},
\p2 = ($(hullnode\currentnode)!#2!90:(hullnode\nextnode) - (hullnode\currentnode)$),
\n2 = {atan2(\y2,\x2)},
\n{delta} = {-Mod(\n1-\n2,360)}
in
{arc [start angle=\n1, delta angle=\n{delta}, radius=#2]}
}
-- cycle
}
\begin{document}
\begin{tikzpicture}
\pgfmathsetlengthmacro\boundary{.4cm}
\node (A) [draw, ellipse, minimum width=3cm, minimum height=6cm] at (0,0) {};
\foreach \i in {0,...,3} {
\node (A\i) [draw, circle, yshift=-0.5cm, outer sep=0.3cm] at ($(A.north)!\i/5!(A.south)$) {\i};
}
\node (B) [draw, ellipse, minimum width=3cm, minimum height=6cm] at (6,0) {};
\foreach \i in {0,...,3} {
\node (B\i) [draw, circle, yshift=-0.5cm, outer sep=0.3cm] at ($(B.north)!\i/5!(B.south)$) {\i};
}
\draw[thick, red] \convexpath{A0, B0}{\boundary};
\draw[thick, red] \convexpath{A0, B2}{\boundary};
\draw[thick, green] \convexpath{A1, B1}{\boundary};
\draw[thick, green] \convexpath{A1, B3}{\boundary};
\draw[thick, blue] \convexpath{A3, B1}{\boundary};
\end{tikzpicture}
\end{document}
答案3
我认为一种简单且非常通用的方法(但结果并不完全相同)是使用线宽、背景和透明度。这样甚至可以使用更复杂的路径:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{shapes}
\pgfdeclarelayer{bg}
\pgfsetlayers{bg,main}
\tikzset{
wrap/.style={
line cap=round,
#1,
line width=21pt,
opacity=0.3,
},
mynode/.style={
draw,
circle,
yshift=-0.5cm,
outer sep=0.3cm
},
group/.style={
draw,
ellipse,
minimum width=3cm,
minimum height=6cm
},
}
\begin{document}
\begin{tikzpicture}
\node (A) [group] at (0,0) {};
\foreach \i in {0,...,3} {
\node (A\i) [mynode] at ($(A.north)!\i/5!(A.south)$) {\i};
}
\node (B) [group] at (6,0) {};
\foreach \i in {0,...,3} {
\node (B\i) [mynode] at ($(B.north)!\i/5!(B.south)$) {\i};
}
\begin{pgfonlayer}{bg}
\draw[wrap=red](A0.center) to[out=0,in=180](B0.center);
\draw[wrap=red](A0.center) to[out=0,in=180](B2.center);
\draw[wrap=green](A1.center) to[out=0,in=180](B1.center);
\draw[wrap=green](A1.center) to[out=0,in=180](B3.center);
\draw[wrap=blue](A3.center) to[out=0,in=180](B1.center);
\end{pgfonlayer}
\end{tikzpicture}
\结束{文档}
我们会得到: