我正在尝试从方向列表生成路径(如数字键盘上所示)。坐标生成正确,但由于我多次调用 \path,因此在每个段上都绘制了箭头。如何更改此代码以仅在第一个段上绘制起始箭头,在最后一个段上绘制终止箭头?我曾尝试在 \foreach 外部放置一个 \path,并在其内部仅放置坐标,但没有成功。
编辑:它应该适用于可选参数中传递的任何箭头形状。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\newcommand{\directedPath}[5][]
{
\edef\start{#2}
\edef\stop{#3}
\edef\step{#4}
\edef\directions{#5}
\coordinate (c0) at (\start);
\foreach [var=\dir, count=\cur] in \directions
{
% current coordinate dx
\pgfmathparse{(1-(1-1/sqrt(2))*mod(\dir, 2))*\step*(mod(\dir-1, 3)-1)}
\edef\dx{\pgfmathresult}
% current coordinate dy
\pgfmathparse{(1-(1-1/sqrt(2))*mod(\dir, 2))*\step*(div(\dir-1, 3)-1)}
\edef\dy{\pgfmathresult}
% previous coordinate index
\pgfmathparse{int(\cur - 1)}
\xdef\prev{\pgfmathresult}
% current coordinate
\coordinate (c\cur) at ($(c\prev) + (\dx, \dy)$);
% draw partial path
\ifnum \cur>1
\path [#1] (c\prev) -- (c\cur);
\fi
}
\path [#1] (\start) -- (c1);
\path [#1] (c\cur) -- (\stop);
}
\begin{document}
\begin{tikzpicture}
\node [draw=green] (Start) at (0, 0) {Start};
\node [draw=red] (End) at (5, 2) {End};
\directedPath[draw=black, >->]{Start}{End}{1.0}{3,6,9,8,7,8,9,6,3}
\end{tikzpicture}
\end{document}
答案1
毫无疑问,这需要通过单一路径完成,但您可以使用turtle
库轻松完成此操作。
只需为每个数字定义一个方向(和一个因子)。
由于direction
键只转动“乌龟”,因此还包括forward
包含to[/tikz/turtle/how]
相对坐标的路径的键direction
和给定的distance
,即
to[/tikz/turtle/how] ++ (<direction>:<distance>)
和只需插入一个到和一个(最后的?)到(或任何Start
当前的样式)。End
move to
(Start)
line to
(End)
how
当然,您可以在数字样式的设置中使用问题中的数学知识,但这样更快(对于 TikZ 和书写而言)。
我选择了网格状输出,它需要sqrt(2)
对角线方向的因子。将此因子设置为以1
获得与问题中相同的距离。(我还稍微改变了示例以获得对称结果。)
我已创建并使用了辅助样式进行设置,以 为标记@
。最好在/aux
路径中简单地定义此样式,因为我们不会再次使用它,或者在/tikz
路径中确实需要它。
1
这也使得通过省略键的值来设置所有因素变得容易(如果没有给出值,则forward
默认为),即/tikz/turtle/distance
@setup turtle digits/.style n args={3}{
/tikz/turtle/#1/.style={
/tikz/turtle/direction=#2,
/tikz/turtle/forward}}
(没有真正的理由将forward
键的值设置为固定距离,因为改变该distance
值会更加一致。)
如果您突然觉得这些键不应该被称为1
,2
,......9
而是1 step
,2 step
,......您只需在 后面9 step
添加。 step
#1
代码
\documentclass[tikz,convert]{standalone}
\usetikzlibrary{turtle}
\tikzset{
@setup turtle digits/.style n args={3}{
/tikz/turtle/#1/.style={
/tikz/turtle/direction=#2,
/tikz/turtle/forward={#3*\pgfkeysvalueof{/tikz/turtle/distance}}}},
@setup turtle digits={1}{south west}{1.41421},
@setup turtle digits={2}{south} {1},
@setup turtle digits={3}{south east}{1.41421},
@setup turtle digits={4}{left} {1},
@setup turtle digits={6}{right} {1},
@setup turtle digits={7}{north west}{1.41421},
@setup turtle digits={8}{north} {1},
@setup turtle digits={9}{north east}{1.41421},
turtle/.cd,
Start/.style={/tikz/insert path={(#1)}},
End/.style={/tikz/insert path={to[/tikz/turtle/how] (#1)}},
Start/.default=Start,
End/.default=End,
}
\begin{document}
\begin{tikzpicture}
\node [draw=green] (Start) at (0, 1) {Start};
\node [draw=red] (End) at (5, 2) {End};
\draw [draw=black, >->] [turtle={Start, 2, 3, 6, 9, 8, 7, 8, 9, 6, 3, End}];
\end{tikzpicture}
\end{document}
输出
有因素
不考虑因素
答案2
以下是单路径版本:
\documentclass{article}
%\url{https://tex.stackexchange.com/q/123997/86}
\usepackage{tikz}
\usetikzlibrary{calc}
\newcommand{\directedPath}[5][]
{
\coordinate (c0) at (#2);
\path (c0)
\foreach [var=\dir,count=\cur] in {#5}
{
++({(1-(1-1/sqrt(2))*mod(\dir, 2))*#4*(mod(\dir-1, 3)-1)},{(1-(1-1/sqrt(2))*mod(\dir, 2))*#4*(div(\dir-1, 3)-1)}) coordinate (c\cur)
};
\path[#1] (#2) -- (c1) \foreach [var=\dir,count=\cur] in {#5}
{
-- (c\cur)
} -- (#3);
}
\begin{document}
\begin{tikzpicture}
\node [draw=green] (Start) at (0, 0) {Start};
\node [draw=red] (End) at (5, 2) {End};
\directedPath[draw=black, >->]{Start}{End}{1.0}{3,6,9,8,7,8,9,6,3}
\end{tikzpicture}
\end{document}
两个 foreach 循环是因为路径的起点和终点都是非零大小的节点,但位移是相对于节点中心的。在第二条路径中,(c1)
由于在使用 foreach 在多个节点之间绘制路径。有关替代解决方案,请参见那里的答案。