Tikz 中是否有办法绘制仅由两个节点指定的路径,从而避开绘图中的区域?

Tikz 中是否有办法绘制仅由两个节点指定的路径,从而避开绘图中的区域?

我想使用简单的语法(如“\draw (SD00) -- (ED03);”)连接一组预定义节点,仅使用起始节点和终止节点,而不是指定通过中间节点的整个路径。唯一的限制是边缘不能跨越彩色框区域。Tikz 中是否有嵌入的算法可以自动计算这样的路线?

 \begin{tikzpicture}
\begin{scope}[xshift=0cm, yshift=-2cm]
  \node[draw, circle] at (0,0)(SD00) {0};
  \node[draw, circle] at (0,1)(SD01) {1};
  \node[draw, circle] at (0,2)(SD02) {2};  
  \node[draw, circle] at (0,3)(SD03) {3};
\end{scope}

\begin{scope}[xshift=7cm, yshift=2cm]
  \node[draw, circle] at (0,0)(ED00) {0};
  \node[draw, circle] at (0,-1)(ED01) {1};
  \node[draw, circle] at (0,-2)(ED02) {2};  
  \node[draw, circle] at (0,-3)(ED03) {3};
  \node[draw, circle] at (0,-4)(ED04) {4};
  \node[draw, circle] at (0,-5)(ED05) {5};  
  \node[draw, circle] at (0,-6)(ED06) {6};
\end{scope}

% forbidden areas
\draw[fill=red!20] (1.5,-3) rectangle ++(4,5) node[below left]{red};
\draw[fill=teal!20] (1.5,3.5) rectangle ++(4,3);
\draw[fill=teal!20] (-2,-5) rectangle ++(7.5,1);

% Connections
\draw[dashed] (SD00) -- (ED03); % simple direct path
\draw[red] (SD00)  -- ++(1,0) to[out=90, in=180] ++(1,5)  -- ++(3,0) to[out=0, in=180] (ED03); % piecewise path

\end{tikzpicture}

在此处输入图片描述

答案1

如果您知道连接的预配置路径,则可以将其打包成一种样式,使用其中可以通过宏和to path访问起始和目标节点。\tikztostart\tikztotarget

在本例中,我定义了一个way around LR以 形式接受参数的键<name 1>:<name 2>。(这需要矩形实际上是节点,因为这比在这里引用它们要容易得多。)

此外,PGFkey 命名空间中定义了三个值/tikz/wayround,您可以通过密钥进行设置。这些值也/tikz/way around可以在内部访问。to path

在这种情况下,路径本身只是使用--|--|路径运算符以及calc库的坐标规范的一系列正交线,其中指定位于点和之间的($(<c1>)!<ratio>!(<c2>)$)点。<ratio><c1><c2>

在这种情况下,按后缀分类LR,这只是一个向东方向的连接。您可以为从右到左的线定义类似的样式,依此类推。(我们也可以将其打包成一种样式,事先进行一些计算,但这只是一个数学问题,而不是 TikZ 问题。)

代码

\documentclass[tikz]{standalone}
\usetikzlibrary{calc,fit}
\newcommand*\wayaroundset{\pgfqkeys{/tikz/wayaround}}
\newcommand*\wayaroundvalueof[1]{\pgfkeysvalueof{/tikz/wayaround/#1}}
\wayaroundset{
   start distance/.initial=1cm,
   target distance/.initial=1cm,
   distance/.style={start distance={#1}, target distance={#1}},
   ratio/.initial=.5}
\tikzset{
   rectangle points/.style={
     fit={#1}, inner sep=+0pt, outer sep=+0pt, shape=rectangle, node contents=},
   way around/.code=\wayaroundset{#1},
   way around LR/.style args={#1:#2}{
       to path={
           (\tikztostart) -- ++(0:\wayaroundvalueof{start distance})
                          |- ($(#1.south)!\wayaroundvalueof{ratio}!(#2.north)$)
                          -| ($(\tikztotarget)+(180:\wayaroundvalueof{target distance})$)
                          -- (\tikztotarget)}}}
\begin{document}
\begin{tikzpicture}
\path[xshift=0cm, yshift=-2cm] foreach \i in {0,...,3} { node[draw, circle] at (0, \i) (SD0\i) {\i} };
\path[xshift=7cm, yshift= 2cm] foreach \i in {0,...,6} { node[draw, circle] at (0,-\i) (ED0\i) {\i} };

% forbidden areas
\node (forbid-a) [draw, fill=red!20,  rectangle points={( 1.5,-3)  (5.5, 2)}];
\node (forbid-b) [draw, fill=teal!20, rectangle points={( 1.5, 3.5)(5.5, 6.5)}];
\node (forbid-c) [draw, fill=teal!20, rectangle points={(-2,  -5)  (5.5,-4)}];

% Connections
\tikzset{every path/.append style=ultra thick}
\draw[blue]  (SD00) to [way around LR=forbid-b:forbid-a]                   (ED03);
\draw[green] (SD01) to [way around={distance=.75cm, ratio=.25},
                        way around LR=forbid-b:forbid-a]                   (ED04);
\draw[red]   (SD03) to [way around={start distance=.5cm}, 
                        way around LR=forbid-a:forbid-c]                   (ED06);
\draw[yellow](SD02) to [way around={start distance=1.25cm, ratio=.25},
                        way around LR=forbid-a:forbid-c]                   (ED05);
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

相关内容