如何使用节点距离来偏移 TikZ 中箭头的起点和/或终点?

如何使用节点距离来偏移 TikZ 中箭头的起点和/或终点?

我想画一个箭头,其中一个端点实际上并没有连接到另一个节点,并且我希望箭头的长度考虑到箭头到的节点的节点距离附件。所以我想写一些类似

\draw [->] ([left of] the-node) -- (the-node);

请参阅下面的 MWE:

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}
\begin{tikzpicture}[
    node/.style={
      node distance=5mm,
    },
  ]
  \node [node] (n) {n};

  % This is what I would like to write (or something like it)
  %\draw [->] ([left of] n) -- (n);

  % Here are my options so far, none of which I like

  % 1:
  \draw [->] ([yshift=5mm] n.north) -- (n);
  % CON: requires explicit use of the node distance

  % 2:
  \coordinate (coord1) at ([xshift=5mm] n.east);
  \draw [->] (coord1) -- (n);
  % CON: requires explicit use of the node distance AND an extra coordinate

  % 3:
  \coordinate [below=of n] (coord2);
  \draw [->] (coord2) -- (n);
  % CON: requires an extra coordinate, and it doesn't seem to use the node
  % distance of 'n' anyway
\end{tikzpicture}
\end{document}

这是 MWE 的结果:

在此处输入图片描述

关于如何实现这一目标,有什么想法吗?

答案1

您可以在左侧使用相对坐标。(在右侧,您必须使用计算。)

\documentclass{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
  \node (n) {n};
  \draw [->] (n.north)+(0,5mm) -- (n);
  \draw [->] (n.east)+(5mm,0) -- (n);
  \draw [->] (n.south)+(0,-5mm) -- (n);
\end{tikzpicture}
\end{document}

一个更简单的解决方案:

\documentclass{standalone}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
  \node (n) {n};
  \draw [<-] (n.north) -- +(0,5mm);
  \draw [<-] (n.east) -- +(5mm,0);
  \draw [<-] (n.south) -- +(0,-5mm);
\end{tikzpicture}
\end{document}

答案2

这是一个简单的解决方案(显示如何使用node distance):

在此处输入图片描述

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}
  \node (n) {n};
  \begin{scope}[node distance=2cm]
    \draw[red,->] coordinate[below=of n] (a) (a) -- (n);
  \end{scope}
  \begin{scope}[node distance=1cm]
    \draw[blue,->] coordinate[left=of n] (a) (a) -- (n);
  \end{scope}
  \begin{scope}[node distance=5mm]
    \draw[green,->] coordinate[right=of n] (a) (a) -- (n);
  \end{scope}
\end{tikzpicture}
\end{document}

答案3

标准范围距离值

node distance设置不是节点的属性,而是周围范围的属性。因此您无法访问“节点距离n正如你所说,但只有“当前节点距离”使用此功能,您可以定义一种使用当前节点距离作为偏移量的样式,如下所示:

my above/.style={yshift=\tikz@node@distance},

现在您可以使用以下形式的坐标([my above] n.center)。不幸的是,必须指定节点锚点,否则 TikZ 将尝试计算节点边界上的一个点,从而忽略yshift过程中的选项。

使用当前节点距离

\begin{tikzpicture}[node distance=5mm]
\node[node distance=20mm] (n) {n}; % node distance does nothing here
\draw[->,red]   ([my above=n] n.center) -- (n);
\draw[->,green] ([my below]n.center) -- (n);
\draw[->,blue]   ([my left]n.center) -- (n);

% Larger node distance for the right line
\begin{scope}[node distance=10mm]
    \draw[->,purple] ([my right]n.center) -- (n);
\end{scope}
\end{tikzpicture}

每个节点的距离值

现在,如果您想在每个节点上存储一个属性,您必须定义一个全局宏,其名称包含节点名称(存储在中\tikz@fig@name),其中包含所需的值:

my distance/.style={execute at end node={%
        \expandafter\gdef\csname my@node@distance@\tikz@fig@name\endcsname{#1}%
}},

样式的作用如下my distance:它定义一个名为 的宏,\my@node@distance@NAME其中NAME是当前声明的节点的名称。此宏包含 中指定的值my distance=10mm,然后可以使用前面提到的名称来访问该值,如样式中所示my above2

my above2/.style={yshift/.expanded=\csname my@node@distance@#1\endcsname },

唯一的缺点是您必须再次指定节点名称作为参数,如([my above2=n] n.center),因为在处理选项时尚未解析节点的名称。所以我们需要额外的参数来告诉它使用节点的存储距离n,而不是其他节点。

请注意,紫色箭头不受上设置的节点距离的影响,仍然使用定义节点时指定scope的值。my distance=10mmn

使用每个节点的距离

\begin{tikzpicture}[node distance=5mm]
\node[my distance=10mm] (n) {n};
\draw[->,red]   ([my above2=n] n.center) -- (n);
\draw[->,green] ([my below2=n] n.center) -- (n);
\draw[->,blue]   ([my left2=n] n.center) -- (n);

% This method is completely unaffected by setting node distance
\begin{scope}[node distance=20mm]
    \draw[->,purple] ([my right2=n]n.center) -- (n);
\end{scope}
\end{tikzpicture}

完整代码

\documentclass[tikz,margin=5pt]{standalone}
\usepackage{tikz}


\begin{document}

\makeatletter
% Basic solution using the current node distance
\tikzset{
    my above/.style={yshift=\tikz@node@distance},
    my below/.style={yshift=-\tikz@node@distance},
    my right/.style={xshift=\tikz@node@distance},
    my left/.style={xshift=-\tikz@node@distance},
}
\begin{tikzpicture}[node distance=5mm]
\node[node distance=20mm] (n) {n}; % node distance does nothing here
\draw[->,red]   ([my above=n] n.center) -- (n);
\draw[->,green] ([my below]n.center) -- (n);
\draw[->,blue]   ([my left]n.center) -- (n);

% Larger node distance for the right line
\begin{scope}[node distance=10mm]
    \draw[->,purple] ([my right]n.center) -- (n);
\end{scope}
\end{tikzpicture}

\vspace{1cm}

% Advanced solution using per-node storage
\tikzset{
    my above2/.style={yshift/.expanded=\csname my@node@distance@#1\endcsname },
    my below2/.style={yshift/.expanded=-\csname my@node@distance@#1\endcsname},
    my right2/.style={xshift/.expanded=\csname my@node@distance@#1\endcsname },
    my left2/.style= {xshift/.expanded=-\csname my@node@distance@#1\endcsname},
    my distance/.style={
        execute at end node={%
            \expandafter\gdef\csname my@node@distance@\tikz@fig@name\endcsname{#1}%
        }%
    },
}
\makeatother

\begin{tikzpicture}[node distance=5mm]
\node[my distance=10mm] (n) {n};
\draw[->,red]   ([my above2=n] n.center) -- (n);
\draw[->,green] ([my below2=n] n.center) -- (n);
\draw[->,blue]   ([my left2=n] n.center) -- (n);

% This method is completely unaffected by setting node distance
\begin{scope}[node distance=20mm]
    \draw[->,purple] ([my right2=n]n.center) -- (n);
\end{scope}
\end{tikzpicture}
\end{document}

答案4

可能有更好的方法来使用\tikz@node@distancewithout \makeatletterand\makeatother但我不知道,所以我愿意接受任何建议。

\documentclass[border=2mm,tikz]{standalone}

\begin{document}
\begin{tikzpicture}
  \node (n) {n};

  \makeatletter
  \begin{scope}[node distance=2cm]
   \draw [->, red]  (n) --++(90:\tikz@node@distance);
   \begin{scope}[node distance=1cm]
   \draw [->, blue]  (n) --++(0:\tikz@node@distance);
   \draw [->, orange]  (n) --++(180:\tikz@node@distance);
   \end{scope}
   \draw [->, green]  (n) --++(-90:\tikz@node@distance);
  \end{scope}
   \makeatother

\end{tikzpicture}
\end{document}

在此处输入图片描述

编辑:下一个代码显示了 percusse 的一个建议:

\documentclass[border=2mm,tikz]{standalone}

\makeatletter
\def\nodedistance{\tikz@node@distance}
\makeatother

\begin{document}
\begin{tikzpicture}
  \node (n) {n};

  \begin{scope}[node distance=2cm]
   \draw [->, red]  (n) --++(90:\nodedistance);
   \begin{scope}[node distance=1cm]
   \draw [->, blue]  (n) --++(0:\nodedistance);
   \draw [->, orange]  (n) --++(180:\nodedistance);
   \end{scope}
   \draw [->, green]  (n) --++(-90:\nodedistance);
  \end{scope}

\end{tikzpicture}
\end{document}

相关内容