我想在直线末尾放置一个标签(大多数情况下是一个字母)。也就是说,节点应该从其端点向直线方向移动,只要不与直线重叠即可。
我知道我能做到
\tikz (a)--node[pos=1.1]{b}(b);
但我不希望节点与线端的距离取决于线的长度。此外,我希望这适用于任意曲线路径,而不仅仅是直线。
在 Tikz 中执行此操作的最简单的方法是什么?
答案1
(这是我第一次添加另一个答案---如果这不是正确的做法,请告诉我;但这与我的第一个答案有很大不同......我应该将其标记为社区维基吗?)
你可以在装饰上使用transform
,因为装饰中的坐标系沿着路径;这会将路径结束后的节点移动第二个参数指定的距离:
\documentclass[border = 2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}
\begin{document}
\begin{tikzpicture}[
endnode/.style n args={2}{
decoration={
markings,
% transform={xshift=0.1*\pgfdecoratedpathlength}, % relative to lenght
transform={xshift=#2}, % absolute
% maybe add a endnodestyle like in Torbjørn T.'s answer
mark=at position 1 with {\node[draw=red] {#1};} % just to debug
},
postaction={decorate},
},
]
\foreach \Ang/\Len in {0/1,45/1.2,90/1.4,135/1.6,180/1.8,225/2,270/2.2,315/2.4}
{
\draw [endnode={A}{2mm}] (0,0) -- (\Ang:\Len);
\draw [endnode={B}{4mm}] (6,0) to[bend right] ++(\Ang:\Len);
}
\end{tikzpicture}
\end{document}
这会使节点沿着路径居中在距路径末端固定距离的位置。遗憾的是,它不会改变节点锚点... 并且auto
在这里不起作用。
答案2
您可以将节点放在pos=1
,然后向左(或向右,取决于位置)对齐它:
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[every node/.style={draw=red},
]
\draw (0,0) -- (1,0) node[right]{a} ;
\draw (1,0.5) --node[pos=1, left]{b} (0,0.5) ;
\draw (0,-1) -- node[pos=1, right]{c} (1, -2) ;
\draw (0,-1.3) -- node[pos=1, sloped, right]{d} (1, -2.3) ;
\draw (0,-2) .. controls (0,-1) and (0.5,-1.5) .. node[pos=1, right]{e} (1, -1) ;
\end{tikzpicture}
\end{document}
答案3
使用库可以稍微接近decorations.markings
。下面的代码利用了markings
装饰具有内部坐标系的事实,其中 x 轴与路径平行,因此我沿 y 轴制作了一条短路径,并auto
沿该路径放置了一个节点。
它并不完美,我不能保证它总是能正常工作。对于to
下面示例中的弯曲路径,我必须将节点旋转 -90 度,但我不确定为什么。您还可以看到节点的位置可能并不完美。
\documentclass[border = 2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}
\begin{document}
\begin{tikzpicture}[
endnode style/.style={},
endnodestyle/.style={endnode style/.append style={#1}},
endnode/.style={
decoration={
markings,
mark=at position 1 with {
\path (0,-1pt) -- node[auto,swap,endnode style] {#1} (0,1pt);
}
},
postaction={decorate}
}
]
\foreach \Ang in {0,45,...,350}
{
% works fine for straight lines
\draw [endnode=a] (0,0) -- (\Ang:2cm);
% needs a rotation for these curved paths
\draw [endnodestyle={rotate=-90},endnode=foo] (6,0) to[bend right] ++(\Ang:2cm);
}
\end{tikzpicture}
\end{document}
输出效果更好,使用不太方便
您可以在路径上保存两个坐标,一个非常接近终点(我pos=0.97
在这里随机使用,但我怀疑理想值将取决于路径),一个在终点(pos=1
)。然后在单独的路径中,使用操作(手册第 14.15 节)计算这两个坐标之间的角度let
,并使用它来设置 的anchor
。这不会出现上述版本遇到的在较大的 时失败的node
问题,但如上所述,使用起来不太方便。decorations.markings
bend angles
\documentclass[border = 2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.markings, calc}
\newcommand{\addnode}[2][tmp]{%
\path let
\p1=($(#1-A)-(#1-B)$),\n1={atan2(\y1,\x1)}
in
node[anchor=\n1] at (#1-B) {#2};
}
\begin{document}
\begin{tikzpicture}
\foreach \Ang in {0,45,...,350}
{
% works fine for straight lines
\draw (0,0) --
coordinate[pos=0.97] (tmp-A) % near end
coordinate[pos=1] (tmp-B) % at end
(\Ang:2cm); % close the path
\addnode{a} % add node in separate step
\draw (6,0) to[bend right=80]
coordinate[pos=0.97] (tmp-A)
coordinate[pos=1] (tmp-B)
++(\Ang:2cm);
\addnode{foo}
}
\end{tikzpicture}
\end{document}
答案4
这是另一个decorations.markings
无需手动调整即可工作的答案:将节点节点放在线的末尾之后,无需旋转,并具有正确的锚点。
诀窍是放置第一个节点作为参考来确定正确的锚点位置。
\documentclass[tikz,border=7pt]{standalone}
\usetikzlibrary{decorations.markings,calc}
\begin{document}
\begin{tikzpicture}[
endnode/.style={
decoration={
markings,
mark=at position .999 with {
\path (0,0) node[overlay](refnode){}
let \p1=(refnode.west), \n1={-atan2(\y1,\x1)} in {
node[anchor=\n1, draw=red] {#1}
};
}
},
postaction={decorate}
}
]
\foreach \Ang in {0,20,...,350}
{
\draw [endnode=a] (0,0) -- (\Ang:2cm);
\draw [endnode=foo] (6,0) to[bend right=77] ++(\Ang:2cm);
}
\end{tikzpicture}
\end{document}
编辑 :正如@Torbjørn T. 在他的评论中所建议的那样,我将其替换pos=1
为pos=.999
以避免由于舍入 tex 错误而消失。我还添加了overlay
参考节点以避免边界框意外。