![PGFkeys 问题。带参数的元箭头提示仅在使用不同线宽时才有效。为什么?](https://linux22.com/image/240830/PGFkeys%20%E9%97%AE%E9%A2%98%E3%80%82%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E5%85%83%E7%AE%AD%E5%A4%B4%E6%8F%90%E7%A4%BA%E4%BB%85%E5%9C%A8%E4%BD%BF%E7%94%A8%E4%B8%8D%E5%90%8C%E7%BA%BF%E5%AE%BD%E6%97%B6%E6%89%8D%E6%9C%89%E6%95%88%E3%80%82%E4%B8%BA%E4%BB%80%E4%B9%88%EF%BC%9F.png)
给出的解决方案这里有问题。让我们重写一个最小示例
\documentclass{standalone}
\usepackage{tikz}
\makeatletter
\tikzset{arrow length/.initial = 6pt,
arrow angle/.initial = 45}
\pgfarrowsdeclare{adj}{adj}{
\pgfarrowsleftextend{0pt}
\pgfarrowsrightextend{.5\pgflinewidth}
}
{
\pgfkeys{/tikz/arrow length/.get=\arrow@length}
\pgfkeys{/tikz/arrow angle/.get=\arrow@angle}
\pgfmathsetlengthmacro{\arrow@angle}{\arrow@length*tan(\arrow@angle)}
\pgfsetdash{}{0pt} % do not dash
\pgfsetroundcap % fix cap
\pgfpathmoveto{\pgfpointorigin}%{\pgfpoint{-4\arrowsize}{4\arrowsize}}
\pgfpathlineto{\pgfpoint{-\arrow@length}{\arrow@angle}}
\pgfpathmoveto{\pgfpointorigin}%{\pgfpoint{-4\arrowsize}{4\arrowsize}}
\pgfpathlineto{\pgfpoint{-\arrow@length}{-\arrow@angle}}
\pgfusepathqstroke
}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw[help lines] (-3,0)grid(3,4);
% Arrow 1
\draw[arrow length = 24pt,
arrow angle = 15,
adj-adj,line width=1.5pt](-2.5,1)--(2.5,1)node[right]{1}
node[above,midway]{First arrow};
% Arrow 2 - Doesn't change anything (same line width then before)
\draw[arrow length = 400cm, %<- Big value to show you it doesn't work
arrow angle = 720, %<- Big value to show you it doesn't work
adj-adj,line width=1.5pt](-2.5,2)--(2.5,2)node[right]{2}
node[above,midway]{Arrows not changed};
% Arrow 3 - Change arrow because the line width is changed
\draw[adj-adj,line width=1.501pt](-2.5,3)--(2.5,3)node[right]{3}%<- Line width little changed
node[above,midway]{Arrows changed};
\end{tikzpicture}
\end{document}
结果如下
问题是箭头长度和箭头角度样式会影响不同线宽的线上的箭头。在箭头 2(参见上面的列表)中,我应用了非常大的值,但没有效果,因为线宽与上一条线相同。在下面的箭头中,我应用了比以前多 0.001pt 的线宽,并且选项会更改箭头尖端。
我是否使用了错误的 pgfkeys?我该如何解决?
答案1
根据 PGF 手册第 611 页:
代码只会执行一次,即第一次需要绘制箭头时。生成的低级驱动程序命令将被协议化并存储起来。在箭头的所有后续使用中,都会直接插入协议化的代码。
但是,代码会针对每个线宽重新执行。因此,线宽为 2pt 的箭头与线宽为 0.4pt 的相同箭头可能会产生不同的协议。
...换句话说,这似乎是一个有意为之的功能。我不确定为什么您需要为单一线宽设置多种不同箭头大小来解决您的原始问题,但如果您确实需要,最好将它们定义为不同的箭头类型。
答案2
Ant 是对的,通常箭头尖端会针对每个线宽计算一次,然后保存。这大大加快了渲染速度。(PGF 称此为原型设计。)但可以指定其他选项,这些选项也应触发重新计算。这可以通过命令\pgfsetarrowoptions
和来完成\pgfgetarrowoptions
。手册在 p613(版本 2.10)中对此进行了解释,并在下文中给出了一个示例。
我在回答中使用了这个TikZ:中途改变路径的颜色指定两条线相交的角度(每次使用时都必须指定)。 那里的链接指向实际使用这个的答案(鉴于我对这个问题给出了几个答案!)。 我认为它与您的情况非常接近,应该可以进行调整,但如果不可以,请直接询问!
答案3
我不知道为什么,但这个列表很好地满足了我的需求
\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\makeatletter
\tikzset{arrow angle/.code = \def\arrow@angle{#1},
arrow angle/.default = 45,
arrow length/.code = \pgfsetarrowoptions{adj}{#1},
arrow length/.default = 4pt
}
\pgfarrowsdeclare{adj}{adj}{
\pgfarrowsrightextend{.5\pgflinewidth}
}
{
\pgfmathsetlengthmacro{\arrow@angle}{\pgfgetarrowoptions{adj}*tan(\arrow@angle)}
\pgfsetdash{}{0pt} % do not dash
\pgfsetroundcap % fix cap
%\pgfsetstrokecolor{red}
\pgfpathmoveto{\pgfpointorigin}
\pgfpathlineto{\pgfpoint{-\pgfgetarrowoptions{adj}}{\arrow@angle}}
\pgfpathmoveto{\pgfpointorigin}
\pgfpathlineto{\pgfpoint{-\pgfgetarrowoptions{adj}}{-\arrow@angle}}
\pgfusepathqstroke
}
\makeatother
\draw[help lines] (-3,0)grid(3,4);
% Arrow 1 - Default value
\draw[line width = 1.5pt, %<---- HERE I SET 1.5pt
arrow length, % 4pt
arrow angle, % 45
adj-adj](-2.5,1)--(2.5,1)node[right]{1}
node[above,midway]{1.5pt};
% Arrow 2
\draw[line width = 2pt,
arrow length = 10pt,
arrow angle = 15,
adj-adj](-2.5,2)--(2.5,2)node[right]{2}
node[above,midway]{2pt};
% Arrow 3
\draw[line width = 1.5pt, %<---- HERE I SET 1.5pt AGAIN
arrow length=1cm,
arrow angle=15,
adj-adj](-2.5,3)--(2.5,3)node[right]{3}%<- Line width little changed
node[above,midway]{1.5pt again but different parameters};
\end{tikzpicture}
\end{document}
结果如下:
它似乎有效。
我想要一个元箭头提示,因为当你画一个非常小的部分,并且你想用 tikz 库间谍缩放它时,结果并不好。要理解我的意思,请参阅这里我发布的图片。有了这个解决方案,我可以完全控制非常小的绘图,而且效果很好。应用到我的绘图上的结果如下
希望它有帮助!