是否可以使 TikZ 中的线帽始终垂直(或水平或 90 度边缘)?也许可以作为选项,line cap
或者甚至作为箭头提示更好。
我想象一种类型vertical
会导致这样的结果
horizontal
看起来像这样
以及90 degree corner
,旋转后其一条边与地平线平行。(除 外triangle 90 degree cap
。)
我创建了带有剪辑的图像,但是剪辑路径不是选项……
答案1
好的,这是使用装饰的第三种方法。在装饰中,变换被设置为坐标变换,这意味着我们可以弄清楚它的作用。这意味着我们可以在变换后的坐标系(其中 x 轴指向沿线,y 轴垂直于线)和页面系统(其中 x 轴为水平,y 轴为垂直)之间切换。我们需要同时使用两者,这就是为什么我不认为这可以通过箭头尖来完成,因为它们是使用帆布变换不能以与坐标变换相同程度的方式进行访问。
更新 2012-05-23改进后的版本,现在可以水平和垂直结束。从主路径到填充的末端有轻微的瑕疵 - 不知道如何处理。还有一个“自动”版本,它根据路径的角度选择“盒子”、“水平”或“垂直”中的“最佳”。
\documentclass{article}
%\url{http://tex.stackexchange.com/q/55671/86}
\usepackage{tikz}
\usetikzlibrary{decorations.markings}
\makeatletter
\def\box@end@box{
\pgfmathsetmacro\boxed@xd{\boxed@xa - \boxed@xo}
\pgfmathsetmacro\boxed@yd{\boxed@yb - \boxed@yo}
\pgfmathsetmacro\boxed@sf{\boxed@xd * \boxed@xc + \boxed@yd * \boxed@yc > 0 ? 1 : -1}
\pgfmathsetmacro\boxed@xd{\boxed@sf * \boxed@xd + \boxed@xo + \boxed@xc}
\pgfmathsetmacro\boxed@yd{\boxed@sf * \boxed@yd + \boxed@yo + \boxed@yc}
}
\def\box@end@horizontal{
\pgfmathsetmacro\boxed@yd{(\boxed@ya - \boxed@yb) *\boxed@yc > 0 ? \boxed@ya + \boxed@yc: \boxed@yb + \boxed@yc}
\pgfmathsetmacro\boxed@xd{(\boxed@ya - \boxed@yb) *\boxed@yc > 0 ? \boxed@xb + (\boxed@ya - \boxed@yb) * \boxed@xc/\boxed@yc: \boxed@xa + (\boxed@yb - \boxed@ya) * \boxed@xc/\boxed@yc}
}
\def\box@end@vertical{
\pgfmathsetmacro\boxed@xd{(\boxed@xa - \boxed@xb) *\boxed@xc > 0 ? \boxed@xa + \boxed@xc: \boxed@xb + \boxed@xc}
\pgfmathsetmacro\boxed@yd{(\boxed@xa - \boxed@xb) *\boxed@xc > 0 ? \boxed@yb + (\boxed@xa - \boxed@xb) * \boxed@yc/\boxed@xc: \boxed@ya + (\boxed@xb - \boxed@xa) * \boxed@yc/\boxed@xc}
}
\def\box@end@auto{
\pgfmathparse{atan2(abs(\boxed@xc),abs(\boxed@yc)) > 60 ? "horizontal" : (atan2(abs(\boxed@xc),abs(\boxed@yc)) > 30 ? "box" : "vertical")}
\csname box@end@\pgfmathresult\endcsname
}
\tikzset{
line cap start/.style={
add line cap={.1}{#1}
},
line cap end/.style={
add line cap={-.1}{#1}
},
line cap type/.style={
line cap start=#1,
line cap end=#1,
},
line end path style/.style={
% draw=red,line width=1pt
fill
},
add line cap/.style 2 args={
decoration={
markings,
mark=at position #1\pgflinewidth with {
\pgfextra{
\pgfpointtransformed{\pgfpointorigin}
\xdef\boxed@xo{\the\pgf@x}
\xdef\boxed@yo{\the\pgf@y}
\pgfpointtransformed{\pgfpoint{0pt}{.5\pgflinewidth}}
\xdef\boxed@xa{\the\pgf@x}
\xdef\boxed@ya{\the\pgf@y}
\pgfpointtransformed{\pgfpoint{0pt}{-.5\pgflinewidth}}
\xdef\boxed@xb{\the\pgf@x}
\xdef\boxed@yb{\the\pgf@y}
\pgfpointtransformed{\pgfpoint{#1\pgflinewidth}{0pt}}
\pgfmathsetmacro\boxed@xc{\boxed@xo - \the\pgf@x}
\pgfmathsetmacro\boxed@yc{\boxed@yo - \the\pgf@y}
\csname box@end@#2\endcsname
\global\let\boxed@xd\boxed@xd
\global\let\boxed@yd\boxed@yd
\global\let\boxed@xc\boxed@xc
\global\let\boxed@yc\boxed@yc
}
\pgftransformreset
\path[line end path style] (\boxed@xa,\boxed@ya) -- (\boxed@xa + \boxed@xc,\boxed@ya + \boxed@yc) -- (\boxed@xd pt,\boxed@yd pt) -- (\boxed@xb + \boxed@xc,\boxed@yb + \boxed@yc) -- (\boxed@xb,\boxed@yb);
}
},
postaction=decorate,
},
}
\makeatother
\begin{document}
\begin{tikzpicture}[line width=1cm]
\draw[line cap type=box] (1,0) .. controls +(1,-2) and +(-1,-1) .. (6,0);
\draw[line cap type=box] (1,-4) .. controls +(1,2) and +(-1,1) .. ++(6,0);
\end{tikzpicture}
\begin{tikzpicture}[line width=1cm]
\draw[line cap type=horizontal] (1,0) .. controls +(1,-2) and +(-1,-1) .. (6,0);
\draw[line cap type=horizontal] (1,-4) .. controls +(1,2) and +(-1,1) .. ++(6,0);
\end{tikzpicture}
\begin{tikzpicture}[line width=1cm]
\draw[line cap type=vertical] (1,0) .. controls +(1,-2) and +(-1,-1) .. (6,0);
\draw[line cap type=vertical] (1,-4) .. controls +(1,2) and +(-1,1) .. ++(6,0);
\end{tikzpicture}
\begin{tikzpicture}[line width=1cm]
\draw[line cap type=auto] (1,0) .. controls +(1,-2) and +(-1,-1) .. (6,0);
\draw[line cap type=auto] (1,-4) .. controls +(1,2) and +(-2,1) .. ++(6,0);
\end{tikzpicture}
\end{document}
结果: