使用 fillbetween 选项填充 TikZ 中的交叉区域

使用 fillbetween 选项填充 TikZ 中的交叉区域

我正在尝试控制填充 TikZ 中的不同交叉区域(包括使用模式),利用以下代码(我不想使用 \addplot,这样我可以根据需要控制曲线的形状)来获取顶部图形。

但到目前为止我成功完成的只是底部的绘图。

我无法填充曲线A和其他路径之间的区域,或者无法精确控制填充所需区域。

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\usetikzlibrary{backgrounds,shadings,patterns}
\begin{document}
%begin curves definitions
\tikzset{pics/.cd,
curvef/.style n args={2}{code={
\node [red] at (#1,#2) (begin){}
([shift={(10.:.4cm)}]begin.center) node (beginr){}
([shift={(60:4.4cm)}]beginr.center) node (midtop){}
([shift={(-60:4.4cm)}]midtop.center) node (end){}
([shift={(-10.:.4cm)}]end.center) node (endr){}
;}}}
%end curves definitions
%
\tikzset{lw/.style={line width=.08cm}}
%
{
\begin{tikzpicture}[scale=.9, transform shape]
\pic at (0,0) {curvef={.8}{0}};
%
\draw[blue, lw, name path=curveA]([shift={(180.:.8cm)}]begin.center) --   (begin.center) to [out=6, in=-160, looseness=1.] (beginr.center) to [out=20, in=-125, looseness=.68] (midtop.center) coordinate (mda) to [out=55, in=160, looseness=.68] node[pos=.74] (r){} (end.center) to [out=-20, in=174, looseness=1.] (endr.center) --  ([shift={(0.:2.6cm)}]endr.center);
%
\pic at (2,0) {curvef={.8}{0}};
%
\draw[green!60!black, lw, name path=curveB] ([shift={(180.:2.8cm)}]begin.center) --  (begin.center) to [out=6, in=-160, looseness=1.] (beginr.center) to [out=20, in=-125, looseness=.68] (midtop.center) coordinate (mdb) to [out=55, in=160, looseness=.68] (end.center) to [out=-20, in=174, looseness=1.] (endr.center) --  ([shift={(0.:.8cm)}]endr.center);
\path[name intersections={of=curveA and curveB}] (intersection-2) node[circle, black, fill=black, scale=0.4] (ab2) {};
%
\path[name path=xaxis] (0,0)(8,0);
%
\draw [name path=red, red, lw, dotted](r.center|-0,0) -- ++(90:4);
\draw [violet, thin, name path=axis] (0,0) -- (9,0);
%
\begin{scope}[on background layer]
\path [fill=yellow, opacity=.5, intersection segments={of=curveB and axis, sequence={L2 -- R3}}];
%
\path [right color=cyan,left color=cyan!20, opacity=.5, intersection segments={of=red and axis, sequence={L* -- R*}}];
%
\path [fill=yellow, opacity=.5, intersection segments={of=curveB and axis, sequence={L2 -- R3}}];
%
\path [pattern=grid, pattern color=gray, opacity=.5, intersection segments={of=red and curveB, sequence={L1 -- R1[reverse]}}];
\fill [red] (ab2) -- ([shift={(40.:.3cm)}]mda) -- ([shift={(40.:.3cm)}]mdb) -- (ab2) -- cycle;
\end{scope}
\end{tikzpicture}
}
%
\end{document}

我需要得到什么我需要得到什么

我得到了什么我得到了什么

在此处输入图片描述

答案1

使用你的方法很难找到两条曲线的最大值,这就是为什么下面的例子省略了灰色部分。用不同的方式绘制曲线可能会更容易,这样实际上最大值处就已经有一个坐标了。顺便说一句,我宁愿使用\coordinates 而不是\nodes。

我还建议您修改 的定义,\pic以便直接用它绘制曲线。请注意,您可以命名\pic,然后引用里面的坐标和节点,如下例所示。还请注意,当您想要填充路径时,最好关闭路径。

\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usetikzlibrary{backgrounds, fillbetween}

\begin{document}

%begin curves definitions
\tikzset{
    pics/curvef/.style n args={3}{code={
        \coordinate (-begin) at #1;
        \coordinate (-beginr) at ([shift={(10:.4cm)}]-begin);
        \coordinate (-midtop) at ([shift={(60:4.4cm)}]-beginr);
        \coordinate (-end) at ([shift={(-60:4.4cm)}]-midtop);
        \coordinate (-endr) at ([shift={(-10:.4cm)}]-end);
        \coordinate (-start) at ([shift={#2}]-begin);
        \coordinate (-stop) at ([shift={#3}]-endr);
        \draw[pic actions] 
            (-start) --
            (-begin) to [out=6, in=-160, looseness=1] 
            (-beginr) to [out=20, in=-125, looseness=.68] 
            (-midtop) to [out=55, in=160, looseness=.68] 
            coordinate[pos=.74] (-r) 
            (-end) to [out=-20, in=174, looseness=1] 
            (-endr) -- 
            (-stop);
    }}
}
%end curves definitions

\tikzset{lw/.style={line width=.08cm}}

\begin{tikzpicture}[scale=.9, transform shape]

\pic[blue, lw, name path global=curveA] (curveA) 
    at (0,0) {curvef={(.8,0)}{(180:.8cm)}{(0:2.8cm)}};

\pic[green, lw, name path global=curveB] (curveB) 
    at (2,0) {curvef={(.8,0)}{(180:2.8cm)}{(0:.8cm)}};

\draw[name path=split, red, lw, dotted]
    (curveA-r |- 0,0) -- ++(90:4) coordinate (split top);
    
\draw[violet, thin, name path=axis] 
    (0,0) -- (8.8,0);

\begin{scope}[on background layer]
    \path[fill=magenta!50, 
        intersection segments={
            of=curveA and axis, sequence={L* -- R*}
        }] -- cycle;
        
    \path[fill=yellow, 
        intersection segments={
            of=curveB and axis, sequence={L* -- R*}
        }] -- cycle;

    \path[fill=green, 
        intersection segments={
            of=split and curveB, sequence={R1 -- L1[reverse]}
        }] -- cycle;

    \path[fill=cyan,
        name path=overlapAB,
        intersection segments={
            of=curveA and curveB, sequence={L3 -- R2}
        }] -- cycle;

    \path[fill=blue!50!cyan,
        intersection segments={
            of=split and overlapAB, sequence={R1 -- L1[reverse] -- R3}
        }] -- cycle;
\end{scope}

\end{tikzpicture}
\end{document}

在此处输入图片描述


至于填充最大值和两条曲线交点之间的区域,如果使用最大值处的坐标定义曲线,事情就会变得容易得多(请注意,曲线不是确切地与您的原始问题相同):

\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usetikzlibrary{backgrounds, fillbetween}

\begin{document}

%begin curves definitions
\tikzset{
    pics/curvef/.style n args={3}{code={
        \coordinate (-begin) at #1;
        \coordinate (-begin right) at ([shift={(1.75,0)}]-begin);
        \coordinate (-top) at ([shift={(2.5,4)}]-begin);
        \coordinate (-top left) at ([shift={(-0.75,0)}]-top);
        \coordinate (-top right) at ([shift={(0.75,0)}]-top);
        \coordinate (-end) at ([shift={(5,0)}]-begin);
        \coordinate (-end left) at ([shift={(-1.75,0)}]-end);
        \coordinate (-start) at ([shift={#2}]-begin);
        \coordinate (-stop) at ([shift={#3}]-end);
        \draw[pic actions] 
            (-start) --
            (-begin) .. controls (-begin right) and (-top left) ..
            (-top) .. controls (-top right) and (-end left) ..
            coordinate[pos=.74] (-r) 
            (-end) --
            (-stop);
    }}
}
%end curves definitions

\tikzset{lw/.style={line width=.8mm}}

\begin{tikzpicture}[scale=.9, transform shape]

\pic[blue, lw, name path global=curveA] (curveA) 
    at (0,0) {curvef={(.8,0)}{(-.8,0)}{(2.8,0)}};

\pic[green, lw, name path global=curveB] (curveB) 
    at (2,0) {curvef={(.8,0)}{(-2.8,0)}{(.8,0)}};

\draw[name path=split, red, lw, dotted]
    (curveA-r |- 0,0) -- (curveA-r |- curveA-top) 
    coordinate (split top);
    
\draw[violet, thin, name path=axis] 
    (0,0) -- (8.6,0);

\begin{scope}[on background layer]
    \path[name intersections={of=curveA and curveB}]
        coordinate (intersectionAB) at (intersection-2);
    
    \path[fill=red!50]
        (intersectionAB) -- (curveA-top) -- (curveB-top) -- cycle;
        
    \path[fill=magenta!50, 
        intersection segments={
            of=curveA and axis, sequence={L* -- R*}
        }] -- cycle;
        
    \path[fill=yellow, 
        intersection segments={
            of=curveB and axis, sequence={L* -- R*}
        }] -- cycle;

    \path[fill=green, 
        intersection segments={
            of=split and curveB, sequence={R1 -- L1[reverse]}
        }] -- cycle;

    \path[fill=cyan,
        name path=overlapAB,
        intersection segments={
            of=curveA and curveB, sequence={L3 -- R2}
        }] -- cycle;

    \path[fill=blue!50!cyan,
        intersection segments={
            of=split and overlapAB, sequence={R1 -- L1[reverse] -- R3}
        }] -- cycle;
\end{scope}

\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容