具有“缩短 >=...”的循环边,该边是对称的并且指向节点

具有“缩短 >=...”的循环边,该边是对称的并且指向节点

TikZ 中的“缩短 >=”选项会导致贝塞尔曲线的形状发生变化。例如,对于循环边缘,它会使循环不对称(图中的节点 A)。

我可以使用 curveto,post=moveto 和 mark 装饰使其对称,但是:

  1. 箭头没有出现在正确的位置。
  2. 它没有指向节点。

参见图中节点B。

可以使用自定义箭头代码并在装饰(节点 C)中手动调整来修复这些问题:

A:不对称环。B:箭头位置和方向错误。C:正确。

以下是代码:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,arrows,decorations.pathmorphing,decorations.markings}
\begin{document}
\begin{tikzpicture}

  \node [circle,draw] (A) at (0, 0) {A};
  \path (A) edge [out=240,in=300,min distance=8mm,-angle 90 reversed,shorten >=6pt] (A);

  \node [circle,draw] (B) at (2, 0) {B};
  \path (B) edge [out=240,in=300,min distance=8mm,
                  decoration={curveto,post=moveto,post length=8pt},
                  postaction={decoration={post length=0,markings,mark=at position 1
                                          with {\arrow{angle 90 reversed}}},decorate},
                  decorate] (B);

  \node [circle,draw] (C) at (4, 0) {C};
  \path (C) edge [out=240,in=300,min distance=8mm,
                  decoration={curveto,post=moveto,post length=8pt},
                  postaction={decoration={post length=0,markings,mark=at position 1
                  with {\draw [-angle 90 reversed] (0, 0) -- 
                        ($(0, 0)!2.5pt!(\tikztotarget.center)$);}},decorate},
                  decorate] (C);

\end{tikzpicture}
\end{document}

但是它有点复杂,需要手动调整。有人知道更好的方法吗?

答案1

我要在这里稍微冒险一下——也许通过说出我要说的话,有人会受到启发来证明我错了。

有谁看到更好的方法吗?

不。

当然,您可以将复杂的代码包装成一个装饰,但在引擎盖下它仍然会做同样的事情。

我的推理是基于 PGF 在修饰路径时可用的信息。这是只是原始路径。PGF 不知道路径实际上是如何指定的。TikZ 知道这一点,但它不会将该信息传递给 PGF。因此,即使您已经写入\draw (C) DoSomethingComplicated (C);[^1],TikZ 也会将调整(C)为节点边界上的某个点,然后忘记(C)您关心的是什么,只将实际坐标传递给 PGF。

因此,PGF 仅获取恰好位于节点边界上的两点之间的路径(C),但 PGF 不知道(C)。您想尽早终止此路径,然后绘制箭头。这似乎在 PGF 的出处之内:对于终止,您可以使用现有的装饰,也可以使用截断贝塞尔曲线的低级宏\pgfpathcurvebetweentime。前一种方法的优点是您可以精确指定截断距离,后一种方法的优点是它更快并且为输出生成实际的贝塞尔曲线(而不是大量短线)。这对于 PGF 来说很容易,因为它只涉及路径和终止标准。

但是,你随后想在路径上放置一个箭头。这时,PGF 知道的并不像你那么多,这一点就变得很重要了。PGF 只知道曲线。因此,它可以计算出曲线在各个点的方向,包括终止点和实际的终点。但是,这些都不是你想要的。您想要的是从终点到终点所看方向的方向。但是从终点开始的方向只能给出该点所在的线,而不是它有多远。由于终点与终点有距离(这更像是整个过程的...点...),您无法从终点的方向确定您应该在哪里看终点,因此 PGF 无法确定将箭头放在哪个方向。因此您需要指定它,这实际上就是您要做的事情。可能存在稍微更简单的指定方向的方法,但可能并不多。

(实际上,当我写这篇文章时,我找到了一种方法,即 PGF 可以使用给出的信息来计算箭头的方向,但计算肯定比你已经拥有的更复杂,所以我将它留给一个比我有更多的时间的 TikZ 爱好者作为练习。)

[^1]:DoSomethingComplicated路径规范目前正在 TeX-SX 实验室中开发。

相关内容