使用 时rounded corners
,我有时会指定一个半径,这个半径对于路径中的大多数角来说看起来都很好,但有几个点太靠近,所以我得到了丑陋的瑕疵。我希望能够将 的半径指定为rounded corners
“目标”或“最大”值,如果点太靠近,半径会自动减小。
考虑以下示例
在第一条路径中,我手动减小了前两个角的半径,而在第二条路径中,所有角的半径都相同,这会引入不必要的尖峰。
是否有一个巧妙的方法可以使路径上的角变圆,而不会引入这些问题?
这是MWE:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\draw [rounded corners=0.5cm] (0,0) -- (2,0) -- (2,1) [rounded corners=1cm] -- (4,1) -- (4,-1);
\draw [rounded corners=1cm] (0,-2) -- (2,-2) -- (2,-1) -- (4,-1) -- (4,-3);
\end{tikzpicture}
\end{document}
答案1
以下是使用装饰的一种方法。对于每个片段,装饰自动机检查圆角的目标半径是否大于片段长度的一半。如果是,则将圆角半径设置为片段长度的一半,否则保持不变。在某些情况下,这种方法会不必要地减小圆角半径,但它避免了必须分析完整路径才能确定每个角的最大可能半径:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations}
\pgfdeclaredecoration{dynamic rounded corners}{initial}{
\state{initial}[width=\pgfdecoratedinputsegmentlength,
next state=middle,
persistent postcomputation=\pgfmathsetmacro\previousroundedendlength{min(\pgfdecorationsegmentlength,\pgfdecoratedinputsegmentlength)}
]{}
\state{middle}[width=\pgfdecoratedinputsegmentlength,next state=middle,
persistent precomputation={
\pgfmathsetmacro\roundedstartlength{min(\previousroundedendlength,\pgfdecoratedinputsegmentlength/2)}
},
persistent postcomputation=\pgfmathsetmacro\previousroundedendlength{min(\pgfdecorationsegmentlength,\pgfdecoratedinputsegmentlength/2)}
]{
\pgfsetcornersarced{\pgfpoint{\roundedstartlength}{\roundedstartlength}}
\pgfpathlineto{\pgfpoint{0pt}{0pt}}
}
\state{final}[if input segment is closepath={\pgfpathclose}]
{
\pgfpathlineto{\pgfpointdecoratedpathlast}
}
}
\tikzset{
dynamic rounded corners/.style={
decorate,
decoration={
dynamic rounded corners,
segment length=#1
}
}
}
\begin{document}
\begin{tikzpicture}[every node/.style={below right, align=center}]
\draw [xshift=-1.5cm, gray!50] (0,0) node {Original\\Path} -- (2,0) -- (1,1) -- (1,3) -- (3,3);
\draw [rounded corners=1cm] node {Normal\\rounded\\corners} (0,0) -- (2,0) -- (1,1) -- (1,3) -- (3,3);
\draw [dynamic rounded corners=1cm,red,xshift=1.5cm] (0,0) node {Dynamic\\rounded\\corners}-- (2,0) -- (1,1) -- (1,3) -- (3,3);
\end{tikzpicture}
\end{document}