我想定义一个 TikZ 样式,将路径变形装饰应用于路径及其每条边,就像样式dashed
应用于所有边一样。这是我的代码:
\documentclass[tikz]{standalone}
\usetikzlibrary{decorations.pathmorphing}
\tikzset{
mysnake/.style={postaction={draw,decorate,decoration={snake,amplitude=1pt,segment length=3pt}}},
allsnake/.style={mysnake,every edge/.style=mysnake},
}
\begin{document}
\begin{tikzpicture}
% works
\path[mysnake] (0,0)--++(1,0);
% compiles but doesn't decorate
\path[mysnake] (0,0.4)edge[]++(1,0);
% decorates both the path and the edges
\path[allsnake] (0,0.8)edge[]++(1,0) (0,1.2)--++(1,0);
% this is fine as well:
\path[allsnake] (0,1.6)edge[]++(1,0);
% this doesn't compile though:
\node[draw] (x) at (0,2){a};
\path[allsnake] (x)edge[]++(1,0);
% this doesn't compile either:
\path[mysnake] (x)edge[]++(1,0);
\end{tikzpicture}
\end{document}
环境中的最后两行tikzpicture
给出了一个错误:“错误:包 pgf 错误:我无法修饰空路径。”注释掉最后两行后的输出为:
有人知道如何解决这个问题,或者如何实现我想要的吗?
答案1
问题似乎是,如果使用裸节点作为坐标,例如(x)
,则构建了一条非平凡路径,因此装饰被激活。但是,该非平凡路径仅由 move-to 组成,因此没有什么可装饰的。
我不太清楚这究竟是怎么发生的(我曾尝试诊断非平凡路径的确切位置,但都无功而返),但这里有一些代码,在装饰路径之前会进行额外的检查,以查看路径是否具有一些可绘制组件。这使用了我的spath3
库,但需要使用一些不在“用户级别”的命令,因此\ExplSyntaxO[n|ff]
。
\documentclass{article}
%\url{https://tex.stackexchange.com/q/699313/86}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing,spath3}
\tikzset{
mysnake/.style={
postaction={
draw,
only if drawable={decorate},
decoration={
snake,
amplitude=1pt,
segment length=3pt
}
}
},
allsnake/.style={
mysnake,
every edge/.style=mysnake
},
}
\ExplSyntaxOn
\tikzset{
only~ if~ drawable/.code={
\tl_set:Nn \l__tikzspath_tikzpath_finish_tl
{
\spath_get_current_path:N \l__tikzspath_tmpa_tl
\spath_bake_round:NV \l__tikzspath_tmpa_tl \l__tikzspath_tmpa_tl
\spath_bake_shorten:NV \l__tikzspath_tmpa_tl \l__tikzspath_tmpa_tl
\spath_reallength:NV \l__tikzspath_tmpa_int \l__tikzspath_tmpa_tl
\int_compare:nNnT {\l__tikzspath_tmpa_int} > {0}
{
\tikzset{#1}
}
}
}
}
\ExplSyntaxOff
\begin{document}
\begin{tikzpicture}
% works
\path[mysnake] (0,0)--++(1,0);
% compiles but doesn't decorate
\path[mysnake] (0,0.4)edge[]++(1,0);
% decorates both the path and the edges
\path[allsnake] (0,0.8)edge[]++(1,0) (0,1.2)--++(1,0);
% this is fine as well:
\path[allsnake] (0,1.6)edge[]++(1,0);
% this doesn't compile though:
\node[draw] (x) at (0,2){a};
\path[allsnake] (x)edge[]++(1,0);
% this doesn't compile either:
\node[draw] (y) at (0,2.4){b};
\path[mysnake] (y)edge[]++(1,0);
\end{tikzpicture}
\end{document}
值得注意的是,这不会导致错误。
答案2
您可以使用坐标而不是节点来修复此问题。例如,您可以指定节点的某个锚点,而不是节点本身。
\documentclass[tikz]{standalone}
\usetikzlibrary{decorations.pathmorphing}
\tikzset{
mysnake/.style={postaction={draw,decorate,decoration={snake,amplitude=1pt,segment length=3pt}}},
allsnake/.style={mysnake,every edge/.style=mysnake},
}
\begin{document}
\begin{tikzpicture}
% works
\path[mysnake] (0,0)--++(1,0);
% compiles but doesn't decorate
\path[mysnake] (0,0.4)edge[]++(1,0);
% decorates both the path and the edges
\path[allsnake] (0,0.8)edge[]++(1,0) (0,1.2)--++(1,0);
% this is fine as well:
\path[allsnake] (0,1.6)edge[]++(1,0);
% this doesn't compile though:
\node[draw] (x) at (0,2){a};
\path[allsnake] (x.east) edge[] ++(1,0);
% % this doesn't compile either:
\path[mysnake] (x.east)edge[]++(1,0);
\end{tikzpicture}
\end{document}