TEX.SX 上给出的业余爱好示例似乎无法与 texlive 2013 一起使用(至少对我来说)。例如,复制 MWE 会产生错误:
\documentclass[tikz,border=2bp]{standalone}
\usetikzlibrary{calc,trees,hobby}
\newcommand{\hobbyconvexpath}[2]{
[
create hobbyhullnodes/.code={
\global\edef\namelist{#1}
\foreach [count=\counter] \nodename in \namelist {
\global\edef\numberofnodes{\counter}
\node at (\nodename)
[draw=none,name=hobbyhullnode\counter] {};
}
\node at (hobbyhullnode\numberofnodes)
[name=hobbyhullnode0,draw=none] {};
\pgfmathtruncatemacro\lastnumber{\numberofnodes+1}
\node at (hobbyhullnode1)
[name=hobbyhullnode\lastnumber,draw=none] {};
},
create hobbyhullnodes
]
($(hobbyhullnode1)!#2!-90:(hobbyhullnode0)$)
\pgfextra{
\gdef\hullpath{}
\foreach [
evaluate=\currentnode as \previousnode using int(\currentnode-1),
evaluate=\currentnode as \nextnode using int(\currentnode+1)
] \currentnode in {1,...,\numberofnodes} {
\xdef\hullpath{\hullpath
..($(hobbyhullnode\currentnode)!#2!180:(hobbyhullnode\previousnode)$)
..($(hobbyhullnode\nextnode)!0.5!(hobbyhullnode\currentnode)$)}
\ifx\currentnode\numberofnodes
\xdef\hullpath{\hullpath .. cycle}
\else
\xdef\hullpath{\hullpath
..($(hobbyhullnode\nextnode)!#2!-90:(hobbyhullnode\currentnode)$)}
\fi
}
}
\hullpath
}
\begin{document}
\begin{tikzpicture}[
every node/.style={black},
every path/.style={red},
scale=3,
transform shape,
use Hobby shortcut
]
\node at (0,0) (a) {A};
\node at (2,0) (b) {B};
\node at (3,0) (c) {C};
\node at (2,-1) (e) {E};
\node at (3,-1) (f) {F};
\node at (0,-1) (d) {D};
\draw \hobbyconvexpath{a,b,c,f,e}{12.5pt};
\end{tikzpicture}
\end{document}
错误说,
Use of \tikz@curveto@double doesn't match its definition \draw \hobbyconvexpath{a,b,c,f,e}{12.5pt}
而且我找不到任何地方报告的错误。所有业余凸路径示例都出现了同样的问题。这是已知的还是我的配置可能有错误?
答案1
克劳迪奥的评论是正确的:问题在于cycle
关键字的使用。
简而言之,我改变了与 TikZ 路径解析器交互的方式hobby
。在过去,a..
意味着 TikZ 将控制权移交给hobby
路径的下一阶段。这意味着除非我想到并为其编程,否则任何“奇怪”的事情都不会发生。这里的“奇怪”是指收集节点、添加选项甚至确保正确处理扩展之类的事情。所有这些都已由 TikZ 路径解析器完成,因此我认为最简单的方法是让 TikZ 做它最擅长的事情并组装路径,但让它hobby
在后台运行并告诉 TikZ 如何处理..
。我希望这会使它更加强大。
但是,有一个地方hobby
可以处理 TikZ 无法处理的事情。那就是规范cycle
。当hobby
处于控制之中时,它可以处理,.. cycle
因为我告诉它遇到这种情况时该怎么做。但是,TikZ 无法处理这种情况,因为它不知道如何处理.. cycle
。原因是cycle
不能放在任何地方,它仅在 line-to 之后有效。所以-- cycle
是有效的(可能在其间有节点或坐标),但cycle
在其他任何地方都无效。特别是,它是不是“路径上的初始点”的简写(不是这样解释的:第一点和最后一点重合的路径hobby
与hobby
hobby
关闭)。
我可以模拟线路检测以确保其.. cycle
有效。下次修改代码时我会考虑这一点。
与此同时,所做cycle
的只是确保选项closed=true
在路径上的某个地方发出。因此,要修复它,我们只需将其放回某个地方。这是上述代码的修改版本,它实现了这一点,并稍微整理了开始和结束。
\documentclass{article}
%\url{http://tex.stackexchange.com/q/121286/86}
\usepackage{tikz}
\usetikzlibrary{calc,trees,hobby}
\newcommand{\hobbyconvexpath}[2]{
[
create hobbyhullnodes/.code={
\global\edef\namelist{#1}
\foreach [count=\counter] \nodename in \namelist {
\global\edef\numberofnodes{\counter}
\node at (\nodename)
[draw=none,name=hobbyhullnode\counter] {};
}
\node at (hobbyhullnode\numberofnodes)
[name=hobbyhullnode0,draw=none] {};
\pgfmathtruncatemacro\lastnumber{\numberofnodes+1}
\node at (hobbyhullnode1)
[name=hobbyhullnode\lastnumber,draw=none] {};
},
create hobbyhullnodes
]
($(hobbyhullnode1)!#2!-90:(hobbyhullnode0)$)
\pgfextra{
\gdef\hullpath{}
\foreach [
evaluate=\currentnode as \previousnode using int(\currentnode-1),
evaluate=\currentnode as \nextnode using int(\currentnode+1)
] \currentnode in {1,...,\numberofnodes} {
\ifnum\currentnode=1\relax
\xdef\hullpath{([closed=true]$(hobbyhullnode\currentnode)!#2!180:(hobbyhullnode\previousnode)$)
..($(hobbyhullnode\nextnode)!0.5!(hobbyhullnode\currentnode)$)}
\else
\xdef\hullpath{\hullpath
..($(hobbyhullnode\currentnode)!#2!180:(hobbyhullnode\previousnode)$)
..($(hobbyhullnode\nextnode)!0.5!(hobbyhullnode\currentnode)$)}
\fi
\ifx\currentnode\numberofnodes
\else
\xdef\hullpath{\hullpath
..($(hobbyhullnode\nextnode)!#2!-90:(hobbyhullnode\currentnode)$)}
\fi
}
}
\hullpath
}
\begin{document}
\begin{tikzpicture}[
every node/.style={black},
every path/.style={red},
scale=3,
transform shape,
use Hobby shortcut
]
\node at (0,0) (a) {A};
\node at (2,0) (b) {B};
\node at (3,0) (c) {C};
\node at (2,-1) (e) {E};
\node at (3,-1) (f) {F};
\node at (0,-1) (d) {D};
\draw \hobbyconvexpath{a,b,c,f,e}{12.5pt};
\end{tikzpicture}
\end{document}