我想绘制一条相对较粗的贝塞尔曲线,一直延伸到矩形的边缘。在下面的 MWE 中,最终的剪裁边界由绘制的矩形表示。
我喜欢从 (0,10) 到 (20,30) 的曲线形状,但我希望那个小的剩余三角形也能被填充。我发现该([turn]...)
语法对于曲线的末端很有效,但对于曲线的起点却不起作用。
我的笨拙解决方案是绘制两次曲线,一次从顶部开始,一次从底部开始,但似乎一定有更好的方法。
在实际使用中,这些曲线并非像 MWE 中那样简单地来自点,而是相对于图像的其他维度参数化的,这就是为什么我不想手动计算切线并对数字进行硬编码。
编辑:我意识到我可能在寻求问题的特定解决方案,而不仅仅是最简单的解决方案。如果有一种方法可以“直线”延伸不涉及([turn]...)
或切线的路径,我也愿意接受这种解决方案。(尽管如此,最初的问题对我来说仍然很有趣。)
\documentclass[tikz, margin=1cm]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\draw (0, 0) rectangle (30, 30);
\draw[line width=1.333cm, line cap=rect] (0, 10) .. controls ($(0, 10)!0.333!(20, 30) + (-1, 1)$) and ($(0, 10)!0.666!(20, 30) + (-1, 1)$) .. (20, 30);
\draw[green, opacity=0.25, line width=1.333cm, line cap=rect] (0, 10) .. controls ($(0, 10)!0.333!(20, 30) + (-1, 1)$) and ($(0, 10)!0.666!(20, 30) + (-1, 1)$) .. (20, 30) -- ([turn]0:2);
\draw[blue, opacity=0.25, line width=1.333cm, line cap=rect] (20, 30) .. controls ($(0, 10)!0.666!(20, 30) + (-1, 1)$) and ($(0, 10)!0.333!(20, 30) + (-1, 1)$) .. (0, 10) -- ([turn]0:2);
\draw[red] (0, 10) -- ($(0, 10)!0.333!(20, 30) +(-1, 1)$) -- ($(0, 10)!0.666!(20, 30) + (-1, 1)$) -- (20, 30);
\end{tikzpicture}
\end{document}
编辑 2:为清楚起见添加了箭头(抱歉,我使用 Preview.app 来添加它们,而不是 TeX :P)
我希望黑线延伸得足够远,这样它就会被矩形“平整”地剪掉,而不会留下那个小的内部三角形。
答案1
假设我理解了要求,使用负值的技巧可能会产生所需的结果shorten >
:shorten <
\documentclass[tikz,border=1cm]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\draw (0, 0) rectangle (30, 30);
\draw [line width=1.333cm, line cap=rect, shorten >=-0.5cm, shorten <=-0.5cm]
(0, 10) .. controls
($(0, 10)!0.333!(20, 30) + (-1, 1)$) and
($(0, 10)!0.666!(20, 30) + (-1, 1)$) ..
(20, 30);
\end{tikzpicture}
\end{document}
答案2
我明白了。现在好些了吗?这在两端增加了一些平滑的延续性。
\documentclass[tikz, margin=1cm]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\draw (0, 0) rectangle (30, 30);
\draw[line width=1.333cm, line cap=rect] (0, 10) .. controls ($(0, 10)!0.333!(20, 30) + (-1, 1)$) and ($(0,
10)!0.666!(20, 30) + (-1, 1)$) .. (20, 30) coordinate[pos=-0.1] (aux1) coordinate[pos=0] (aux2)
coordinate[pos=1.1] (aux3) coordinate[pos=1] (aux4)
(aux1) -- (aux2) (aux3) -- (aux4);
\end{tikzpicture}
\end{document}
当然,你可以将其作为一种风格。
\documentclass[tikz, margin=1cm]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[continuation/.style={insert path={coordinate[pos=-#1] (aux1) coordinate[pos=0] (aux2)
coordinate[pos=1+#1] (aux3) coordinate[pos=1] (aux4)
(aux1) -- (aux2) (aux3) -- (aux4)}}]
\draw (0, 0) rectangle (30, 30);
\draw[line width=1.333cm, line cap=rect] (0, 10) .. controls ($(0, 10)!0.333!(20, 30) + (-1, 1)$) and ($(0,
10)!0.666!(20, 30) + (-1, 1)$) .. (20, 30) [continuation=0.1];
\end{tikzpicture}
\end{document}
并制作强制性动画
\documentclass[tikz, margin=1cm]{standalone}
\usetikzlibrary{calc}
\begin{document}
\tikzset{continuation/.style={insert path={coordinate[pos=-#1] (aux1) coordinate[pos=0] (aux2)
coordinate[pos=1+#1] (aux3) coordinate[pos=1] (aux4)
(aux1) -- (aux2) (aux3) -- (aux4)}}}
\foreach \X in {0.01,0.02,...,0.25}
{\begin{tikzpicture}
\draw (0, 0) rectangle (30, 30);
\draw[line width=1.333cm, line cap=rect] (0, 10) .. controls ($(0, 10)!0.333!(20, 30) + (-1, 1)$) and ($(0,
10)!0.666!(20, 30) + (-1, 1)$) .. (20, 30) [continuation=\X];
\end{tikzpicture}}
\end{document}
答案3
我已决定采用以下利用decorations.markings
TikZ 库的解决方案。
\documentclass[tikz, margin=1cm]{standalone}
\usetikzlibrary{calc}
\usetikzlibrary{decorations.markings}
\begin{document}
\begin{tikzpicture}[
continuation/.style={
decoration={
markings,
mark=
at position 0
with {\draw[red, thin] (0.1, 0) -- (-1, 0);},
mark=
at position 0.99999
with {\draw[blue, thin] (-0.1, 0) -- (1, 0);}
},
postaction=decorate,
}]
\draw (0, 0) rectangle (30, 30);
\draw[line width=1.333cm, continuation] (0, 10) .. controls ($(0, 10)!0.333!(20, 30) + (-1, 1)$) and ($(0, 10)!0.666!(20, 30) + (-1, 1)$) .. (20, 30);
\draw[red] (0, 10) -- ($(0, 10)!0.333!(20, 30) + (-1, 1)$) -- ($(0, 10)!0.666!(20, 30) + (-1, 1)$) -- (20, 30);
\draw[green, shorten >=-0.5cm] ($(0, 10)!0.333!(20, 30) +(-1, 1)$) -- (0, 10);
\draw[green, shorten >=-0.5cm] ($(0, 10)!0.666!(20, 30) +(-1, 1)$) -- (20, 30);
\end{tikzpicture}
\end{document}
这里有两个考虑因素。首先,这是否会产生实际切线?贝塞尔曲线末端的红色和蓝色延伸是由continuation
使用 的样式产生的markings
。我在这里通过用绿色绘制穿过贝塞尔曲线的切线并用 延长它来确认这一点shorten >=-0.5cm
。放大两端可以确认这些是相同的线。(我想我可以尝试从 PDF 中提取实际路径并进行数学检查,但……这不是今天的项目。)
第二个考虑是错误在markings
库中。在这种情况下,可以设置的最远结束位置是0.99999
;再一个9
会导致错误。通过检查这张图片,因为我知道我将使用的贝塞尔曲线不会是也末端弯曲,我认为这样很好。
我考虑过在贝塞尔曲线上进行“计算”并手动插入“完美”的延长线,但这似乎不太浪费我的时间,尤其是因为我想参数化我的最终图像。