使用 TikZ 标记放置箭头

使用 TikZ 标记放置箭头

使用装饰库可以将箭头尖端放置在路径上的任意位置。TikZ 将箭头的前端放置在指定位置,这通常正是人们想要的。但是,有时我发现如果将箭头尖端的中间放置在指定位置会更好看,特别是当将箭头置于一条线的中心时:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{decorations.markings,arrows}

\begin{document}

\begin{tikzpicture}[
    decoration={markings,mark=at position 0.5 with {\arrow{triangle 60}}},
    ]
    \draw[postaction={decorate}] (0,0.2) -- (1,0.2);
    \draw[postaction={decorate}] (1,-0.2) -- (0,-0.2);
\end{tikzpicture}

\end{document}

给出

我想要的是

代替

我想要的是

我通过猜测箭头的前端应该在哪里以使箭头的中心位于路径的中间来制作第二张图片。

有没有办法让 TikZ 以这种方式定位箭头(而不必猜测位置)?

答案1

更好地放置箭头的第一步是能够将箭头沿着路径移动一段给定的距离,例如将箭头放置在路径中间左侧 3pt 处。

因此我开始查看 中的代码pgflibrarydecorations.markings。位置计算由 完成\pgf@lib@dec@parsenum。起初我以为我可以简单地在该宏周围放置一个包装器,将任何输入拆分为+加数,分别计算每个加数的长度,然后将它们加在一起。不幸的是,这不起作用:宏从总长度中减去负值,因此0.5-3pt将变成 0.5*(总长度) + (总长度) - 3pt。所以我重写了整个宏。

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}

\makeatletter
% overwrite the number parsing macro from pgflibrarydecorations.markings
\def\pgf@lib@dec@parsenum#1{%
    \gdef\pgf@lib@dec@computed@width{0 pt}%
    \tsx@pgf@lib@dec@parsenum#1+endmarker+%
    \ifdim\pgf@lib@dec@computed@width<0pt\relax%
        \pgfmathparse{\pgfdecoratedpathlength\pgf@lib@dec@computed@width}
        \edef\pgf@lib@dec@computed@width{\pgfmathresult pt}%
    \fi%
}

\def\tsx@pgf@lib@dec@parsenum@endmarker{endmarker}

% this is iterated over all numbers that are summed
\def\tsx@pgf@lib@dec@parsenum#1+{
    \def\temp{#1}%
    \ifx\temp\tsx@pgf@lib@dec@parsenum@endmarker%
    \else%
        \tsx@pgf@lib@dec@parsenum@one{#1}%
        \expandafter\tsx@pgf@lib@dec@parsenum%
    \fi%
}

% calculate the length for each number
\def\tsx@pgf@lib@dec@parsenum@one#1{%
  \pgfmathparse{#1}%
  \ifpgfmathunitsdeclared%
    \pgfmathparse{\pgf@lib@dec@computed@width + \pgfmathresult pt}%
  \else%
    \pgfmathparse{\pgf@lib@dec@computed@width + \pgfmathresult*\pgfdecoratedpathlength*1pt}%
  \fi%
  \edef\pgf@lib@dec@computed@width{\pgfmathresult pt}%
}
\makeatother

\begin{document}
\begin{tikzpicture}
    \draw[decoration={
        markings,
        mark={at position 0.5 + -1cm with {\arrow{>}}},
        },
        postaction={decorate}
        ]
        (0,0) to [out=30, in=150] (4,0);
\end{tikzpicture}
\end{document}

例子

这是我第一次编写这种类型的迭代宏。所以也许有人可以告诉我这是否是“正确”的方法。此外,有没有一种简单的方法可以在输入中同时允许加号和减号,例如而0.5-1cm不是0.5+-1cm?(我知道,我不应该把问题变成答案……)

答案2

您可以自己绘制箭头,而不必使用“箭头”库:

\begin{tikzpicture}[
  decoration={markings,mark=at position 0.5 with {\fill (2pt,0)--(-2pt,2.31pt)--(-2pt,-2.31pt)--cycle;}},
   ]
   \draw[postaction={decorate}] (0,0.2) -- (1,0.2);
   \draw[postaction={decorate}] (1,-0.2) -- (0,-0.2);
\end{tikzpicture}

使用预定义箭头时获得的标记具有提示在 (0,0) 处。此标记将是一个三角形居中在(0,0)。

当然,如果你的路径是弯曲的,效果就没那么好了。箭头尖端可能不在路径上。

相关内容