我正在尝试控制填充 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
使用你的方法很难找到两条曲线的最大值,这就是为什么下面的例子省略了灰色部分。用不同的方式绘制曲线可能会更容易,这样实际上最大值处就已经有一个坐标了。顺便说一句,我宁愿使用\coordinate
s 而不是\node
s。
我还建议您修改 的定义,\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}