自定义形状(可能是图像)作为 tikz 箭头形状

自定义形状(可能是图像)作为 tikz 箭头形状

我浏览过arrows.meta图书馆arrows。它们非常棒。

但是,我想要一个自定义图像/形状作为箭头尖,例如,手套图像作为箭头尖或 $PO_4^{3-}$ 组的形状作为箭头尖。

我查看了\pgfdeclarearrow宏。我无法\node在这个宏中使用;也无法\includegraphics在其中放置。​​代码的尝试基本上是使用手册中给出的以下代码进行多次反复试验(更新:添加了 MWE)

\RequirePackage{luatex85}
\documentclass[crop,tikz]{standalone}
\usepackage{pgfplots}
\usepackage{tikz}
\usetikzlibrary{arrows,arrows.meta}
\begin{document}

\pgfdeclarearrow{
    name = foo,
    parameters = { \the\pgfarrowlength },
    setup code = {
        % The different end values:
        \pgfarrowssettipend{.25\pgfarrowlength}
        \pgfarrowssetlineend{-.25\pgfarrowlength}
        \pgfarrowssetvisualbackend{-.5\pgfarrowlength}
        \pgfarrowssetbackend{-.75\pgfarrowlength}
        % The hull
        \pgfarrowshullpoint{.25\pgfarrowlength}{0pt}
        \pgfarrowshullpoint{-.75\pgfarrowlength}{.5\pgfarrowlength}
        \pgfarrowshullpoint{-.75\pgfarrowlength}{-.5\pgfarrowlength}
        % Saves: Only the length:
        \pgfarrowssavethe\pgfarrowlength
    },
    drawing code = {
        % Attempt here.
        \pgfsetdash{}
        \pgftext[left]{$X$}
        \pgfusepathqfill
    },
    defaults = {length=4}
}

\begin{tikzpicture}[scale=1, every node/.style={} ]
    \node[thick] at (0,0) {+};
    \draw[gray!20] (-5,-5) grid (5,5);
    \draw[foo-foo] (0,0) -- (3cm,0);
    %\draw[-foo] (0,1) -- (10cm,1);
\end{tikzpicture}    

\end{document}

这是我第一次尝试anything在 tikz 中编写自定义内容。我有一个可行的解决方案,我放置一个具有给定形状或图形的节点,并绘制一个箭头直到它接触到它的边界。但如果我可以利用 pgf 内部实现相同的功能,那就太好了。

答案1

该包tikz-cd提供了使用任意东西作为箭头尖头的机会。例如

\documentclass[border=10pt,tikz]{standalone}
\usepackage{tikz-cd}
\begin{document}

\def\POfourthree{PO_4^{3-}}
\def\exampleimagea{\includegraphics[height=2ex]{example-image-a}}

\tikzset{
    PO43/.tip={Glyph[glyph math command=POfourthree,glyph length=3em]},
    exA/.tip={Glyph[glyph math command=exampleimagea,glyph length=3ex]},
}

\tikz[line width=.53pt]\draw[-PO43](0,0)to[bend right](3,0);
\tikz[line width=.53pt]\draw[-exA](0,0)to[bend right](3,0);
\tikz[line width=.53pt]\draw[PO43-exA](0,0)to[bend right](3,0);

\end{document}


如您所见,该内容可能被不恰当地剪辑。以下是如何修复它

\makeatletter
\pgfqkeys{/pgf/arrow keys}{
    glyph width/.code={\pgfarrowsaddtooptions{\pgfmathsetlengthmacro\tikzcd@glyph@wid{#1}}},
}
\pgfdeclarearrow{
  name=Tall Glyph,
  cache=false,
  bending mode=none,
  parameters={\tikzcd@glyph@len,\tikzcd@glyph@wid,\tikzcd@glyph@shorten},
  setup code={
    \pgfarrowssettipend{\tikzcd@glyph@len\advance\pgf@x by\tikzcd@glyph@shorten}},
  defaults={
    glyph axis=axis_height,
    glyph length=+0.9ex,
    glyph width=+3.0ex,
    glyph shorten=+-0.1ex},
  drawing code={
    \show\tikzcd@glyph@wid
    \pgfpathrectangle{\pgfpoint{+0pt}{.5ex-.5*\tikzcd@glyph@wid}}%
                     {\pgfpoint{+\tikzcd@glyph@len}{\tikzcd@glyph@wid}}%
    \pgfusepathqclip%
    \pgftransformxshift{+\tikzcd@glyph@len}%
    \pgftransformyshift{+-\tikzcd@glyph@axis}%
    \pgftext[right,base]{\tikzcd@glyph}}}
\tikzset{
    PO43/.tip={Tall Glyph[glyph math command=POfourthree,glyph length=3em,glyph width=4ex]},
    exA/.tip={Tall Glyph[glyph math command=exampleimagea,glyph length=3ex,glyph width=4ex]},
}

\tikz[line width=.53pt]\draw[-PO43](0,0)to[bend right](3,0);
\tikz[line width=.53pt]\draw[-exA](0,0)to[bend right](3,0);
\tikz[line width=.53pt]\draw[PO43-exA](0,0)to[bend right](3,0);

答案2

虽然不是真正的箭(我尝试过但失败了),但它仍然很有用:

\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\usepackage{graphicx}
\usetikzlibrary{decorations.markings}
\def\hand{\includegraphics[width=3mm]{hand.png}}
\tikzset{
 -hand/.style = {
    decoration = { 
       markings, 
       mark=at position -4mm with { \node[anchor=190,transform shape, inner sep=0pt] {\hand}; } },
       postaction = decorate,
       shorten >=4mm,
    }
}

\begin{document}
\begin{tikzpicture}
    \node[draw] (start) at (0,0) {Start};
    \node[draw] (finish) at (1,2) {Finish};
    \draw[-hand] (start) to[bend left] (finish);
    \draw[-hand] (finish) to[bend left] (start);
\end{tikzpicture}
\end{document}

结果

更新:处理边缘

此技巧也可以与 s 一起使用edge。以下示例显示了如何使用(-hand必须在 中使用选项edge):

\tikzset{
 -hand/.style = {
    decoration = { 
       markings, 
       mark=at position -3mm with { \node[anchor=west,transform shape, inner sep=0pt] {\hand}; } },
       postaction = decorate,
       shorten >=3mm,
    }
}
\begin{tikzpicture}
    \node[draw] (start) at (0,0) {Start};
    \node[draw] (finish) at (1,2) {Finish};
    \draw (start) edge[bend right, -hand] (finish)
          (finish) edge[bend right, -hand] (start);
\end{tikzpicture}

结果:

带边的结果

更新的更新

由于某些未知原因,“边缘”版本的表现优于路径版本,因为作为装饰的“箭头”所需的位置与所包含图片的宽度完全匹配(-3mm),并且选项可以使用相同的值(3mm)shorten >。在路径版本中需要额外的手动微调,但在该edge版本中这不是必需的。这样可以轻松地参数化箭头的大小,如下所示:

\tikzset{
 -hand/.style = {
    decoration = { 
       markings, 
       mark=at position -#1 with { 
           \node[anchor=west, transform shape, inner sep=0pt] 
                 {\includegraphics[width=#1]{hand.png}}; 
          }
       },
       postaction=decorate,
       shorten >=#1,
    },
 -hand/.default=3mm,
}

这样,我们可以指定手的大小(默认为 3 毫米),如下例所示:

\begin{tikzpicture}
    \node[draw] (start) at (0,0) {Start};
    \node[draw] (finish) at (1,2) {Finish};
    \draw (start) edge[bend right, -hand] (finish)
         (finish) edge[bend right, -hand=5mm] (start);
\end{tikzpicture}

结果

相关内容