这个问题很可能只是一厢情愿,但请考虑以下 MWE,它会创建两个 tikz 路径:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\path[fill=blue] (0,0) to[out=0, in=180] (2,1) -- (2,1.5) to[out=180, in=0] (0,0.5);
\path[fill=red] (0,0) to[out=0, in=180] (2,-1) -- (2,-0.5) to[out=180, in=0] (0,0.5);
\end{tikzpicture}
\end{document}
我想以某种方式结合这两条路径来获得如下所示的东西:
这个想法是以一种平滑的方式将它们结合在一起。
澄清一下,我希望的是将两条路径作为输入并将它们进行变换以获得组合和平滑的路径 - 请参阅下文了解原因。
或者,如果有办法将它们合并在一起,然后像这样平滑所有角,那么我也可以这样做。(抱歉画得不太好,希望你能明白我的意思。)
我最终的目标是绘制像这样的图表
...但我并不是要求用代码来绘制这个图表。这将是我为绘制此类图表而编写的库的一部分。我希望实现一种自动绘制阴影区域分割部分的方法,而不必每次都单独指定曲线。
我的想法是,我可以将一些复杂的路径拆分成多个部分,然后将它们合并在一起 - 在示例中它将是这样的
但是,如果我将红色、绿色和黄色路径合并在一起(或将它们相互覆盖),它们连接处就会出现尖角,而连接处理想情况下应该是平滑的。因此,如果能以某种方式平滑这些角,图表看起来会好得多。
正如我所说的,我有点想象这是不可能的,但我经常对 tikz 中可能发生的事情感到惊讶,所以我认为值得一问。
答案1
第一种方法,使用直线和圆弧,可以如下:
\documentclass[tikz,border=1.618mm]{standalone}
\begin{document}
\begin{tikzpicture}
\fill[scale=0.41,yshift=3cm]% the yshift is only for comparison
(0,0) arc (90:50:2.7) --++ (-40:1.9) arc (230:270:2.7) --++ (0,1.2)
arc (270:230:2.7) --++ (140:1) arc (230:130:0.8) --++ (40:1)
arc (130:90:2.7) --++ (0,1.2) arc (90:130:2.7) --++ (220:1.9)
arc (310:270:2.7) -- cycle;
% original paths
\path[fill=blue] (0,0) to[out=0, in=180] (2,1) -- (2,1.5) to[out=180, in=0] (0,0.5);
\path[fill=red] (0,0) to[out=0, in=180] (2,-1) -- (2,-0.5) to[out=180, in=0] (0,0.5);
\end{tikzpicture}
\end{document}
答案2
另一种方法采用您已有的路径:
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\path[fill=blue] (0,0.25) to[out=0, in=180] (2,1.25) --
(2,0.75) to[out=180, in=180, looseness=2] (2,-0.75) --
(2,-1.25) to[out=180, in=0] (0,-0.25) -- cycle;
\end{tikzpicture}
\end{document}
或者也许是基于这样的\pic
:
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\begin{document}
\tikzset{
pics/fork/.style n args={3}{
code={
\coordinate (-A) at #1; \path (-A);
\pgfgetlastxy{\forkcoordax}{\forkcoorday}
\coordinate (-B) at #2; \path (-B);
\pgfgetlastxy{\forkcoordbx}{\forkcoordby}
\coordinate (-C) at #3; \path (-C);
\pgfgetlastxy{\forkcoordcx}{\forkcoordcy}
\pgfmathsetmacro{\forkdist}{
min(
veclen(\forkcoordbx-\forkcoordax,\forkcoordby-\forkcoorday),
veclen(\forkcoordcx-\forkcoordax,\forkcoordcy-\forkcoorday)
)
}
\path[pic actions]
(-A) to[out=0, in=180] (-B)
to[out=180, in=180, distance={\forkdist *0.5pt}] (-C)
to[out=180, in=0] (-A);
}
}
}
\begin{tikzpicture}
\pic[red, fill, draw, very thick] at (0,1)
{fork={(0,0)}{(2,0.75)}{(2,-0.75)}};
\pic[blue, fill, draw, line width=0.5cm, rotate=180] at (0,-1)
{fork={(0,0)}{(2,0.75)}{(2,-0.75)}};
\end{tikzpicture}
\end{document}
这或多或少也应该适用于您在最新编辑中所展示的内容:
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\begin{document}
\tikzset{
pics/fork/.style n args={3}{
code={
\coordinate (-A) at #1; \path (-A);
\pgfgetlastxy{\forkcoordax}{\forkcoorday}
\coordinate (-B) at #2; \path (-B);
\pgfgetlastxy{\forkcoordbx}{\forkcoordby}
\coordinate (-C) at #3; \path (-C);
\pgfgetlastxy{\forkcoordcx}{\forkcoordcy}
\pgfmathsetmacro{\forkdist}{
min(
veclen(\forkcoordbx-\forkcoordax,\forkcoordby-\forkcoorday),
veclen(\forkcoordcx-\forkcoordax,\forkcoordcy-\forkcoorday)
)
}
\path[pic actions]
(-A) to[out=0, in=180] (-B)
to[out=180, in=180, distance={\forkdist *0.5pt}] (-C)
to[out=180, in=0] (-A);
}
}
}
\begin{tikzpicture}
\pic[blue, fill, draw, line width=0.5cm] (fork A) at (0,0)
{fork={(0,0)}{(2,0.75)}{(2,-0.75)}};
\pic[blue, fill, draw, line width=0.5cm] (fork B) at (fork A-C)
{fork={(0,0)}{(2,0)}{(2,-1.25)}};
\pic[blue, fill, draw, line width=0.5cm] (fork C) at (fork A-B)
{fork={(0,0)}{(2,-0.5)}{(2,0.5)}};
\pic[blue, fill, draw, line width=0.5cm] (fork D) at ([xshift=1cm]fork C-B)
{fork={(0,0)}{(2,-2)}{(2,0)}};
\draw[blue, line width=0.5cm] (fork C-B) -- (fork D-A);
\end{tikzpicture}
\end{document}
诚然,事情可能看起来有点奇怪,如果是两个分支之间的距离太小,或者两个分支的末端距离太远X位置。好吧,至少它可以作为一个起点……