我正在使用曲线坐标绘制两个“电视屏幕”,并希望前面的屏幕遮挡另一个屏幕。我想使用 \fillbetween 在外面的屏幕内进行绘制,但由于所有边都是弯曲的,因此我无法仅通过引用两条曲线来实现。有没有办法 \fillbetween 限制内部的多条曲线?
\documentclass{article}
\usepackage{pgfplots}
\usepackage{tikz}
\usepgfplotslibrary{fillbetween}
\begin{document}
\newcommand{\xa}{0.1}
\newcommand{\xb}{0.7}
\newcommand{\ya}{0.8}
\newcommand{\yb}{-0.2}
\newcommand{\za}{1}
\begin{tikzpicture}[scale=1]
\begin{axis}[
axis equal,
hide axis
]
\renewcommand{\za}{0.5}
\addplot [name path=A1,domain=0:1, samples=100,draw=black,line width=1pt] ({ ((1-x)*\xa + x*\xb)/sqrt(((1-x)*\xa + x*\xb)^2 + (\ya)^2+ (\za)^2) }, { (\ya)/sqrt(((1-x)*\xa + x*\xb)^2 + (\ya)^2+ (\za)^2) });
\addplot [name path=A2,domain=0:1, samples=100,draw=black,line width=1pt] ({ ((1-x)*\xa + x*\xb)/sqrt(((1-x)*\xa + x*\xb)^2 + (\yb)^2+ (\za)^2) }, { (\yb)/sqrt(((1-x)*\xa + x*\xb)^2 + (\yb)^2+ (\za)^2) });
\addplot [name path=A3,domain=0:1, samples=100,draw=black,line width=1pt] ({ (\xa)/sqrt((\xa)^2 + ((1-x)*\ya + x*\yb)^2 + (\za)^2) }, { ((1-x)*\ya + x*\yb)/sqrt((\xa)^2 + ((1-x)*\ya + x*\yb)^2 + (\za)^2) });
\addplot [name path=A4,domain=0:1, samples=100,draw=black,line width=1pt] ({ (\xb)/sqrt((\xb)^2 + ((1-x)*\ya + x*\yb)^2 + (\za)^2) }, { ((1-x)*\ya + x*\yb)/sqrt((\xb)^2 + ((1-x)*\ya + x*\yb)^2 + (\za)^2) });
\renewcommand{\za}{1}
\addplot [name path=B1,domain=0:1, samples=100,draw=black,line width=1pt] ({ ((1-x)*\xa + x*\xb)/sqrt(((1-x)*\xa + x*\xb)^2 + (\ya)^2+ (\za)^2) }, { (\ya)/sqrt(((1-x)*\xa + x*\xb)^2 + (\ya)^2+ (\za)^2) });
\addplot [name path=B2,domain=0:1, samples=100,draw=black,line width=1pt] ({ ((1-x)*\xa + x*\xb)/sqrt(((1-x)*\xa + x*\xb)^2 + (\yb)^2+ (\za)^2) }, { (\yb)/sqrt(((1-x)*\xa + x*\xb)^2 + (\yb)^2+ (\za)^2) });
\addplot [name path=B3,domain=0:1, samples=100,draw=black,line width=1pt] ({ (\xa)/sqrt((\xa)^2 + ((1-x)*\ya + x*\yb)^2 + (\za)^2) }, { ((1-x)*\ya + x*\yb)/sqrt((\xa)^2 + ((1-x)*\ya + x*\yb)^2 + (\za)^2) });
\addplot [name path=B4,domain=0:1, samples=100,draw=black,line width=1pt] ({ (\xb)/sqrt((\xb)^2 + ((1-x)*\ya + x*\yb)^2 + (\za)^2) }, { ((1-x)*\ya + x*\yb)/sqrt((\xb)^2 + ((1-x)*\ya + x*\yb)^2 + (\za)^2) });
\addplot[green!20] fill between [of = A1 and A2, soft clip = {domain = -1:1}];
\end{axis}
\end{tikzpicture}
\end{document}
答案1
您可以将常规\path
和\fill
命令与结合使用intersection segments
。但是这样您一次只能将两条路径拼接在一起,因此您需要执行几个步骤。
如果希望较小的屏幕显示在较大的屏幕上,则需要更改绘制它们的顺序(或使用background
s)。
\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\pgfplotsset{compat=1.18}
\begin{document}
\newcommand{\xa}{0.1}
\newcommand{\xb}{0.7}
\newcommand{\ya}{0.8}
\newcommand{\yb}{-0.2}
\newcommand{\za}{1}
\begin{tikzpicture}[scale=1]
\begin{axis}[
axis equal,
hide axis
]
\renewcommand{\za}{0.5}
\addplot[name path=A1, domain=0:1, samples=100, draw=black, line width=1pt]
({ ((1 - x)*\xa + x*\xb)/sqrt(((1 - x)*\xa + x*\xb)^2 + (\ya)^2 + (\za)^2) },
{ (\ya)/sqrt(((1 - x)*\xa + x*\xb)^2 + (\ya)^2 + (\za)^2) });
\addplot[name path=A2, domain=0:1, samples=100, draw=black, line width=1pt]
({ ((1 - x)*\xa + x*\xb)/sqrt(((1 - x)*\xa + x*\xb)^2 + (\yb)^2 + (\za)^2) },
{ (\yb)/sqrt(((1 - x)*\xa + x*\xb)^2 + (\yb)^2 + (\za)^2) });
\addplot[name path=A3, domain=0:1, samples=100, draw=black, line width=1pt]
({ (\xa)/sqrt((\xa)^2 + ((1 - x)*\ya + x*\yb)^2 + (\za)^2) },
{ ((1 - x)*\ya + x*\yb)/sqrt((\xa)^2 + ((1 - x)*\ya + x*\yb)^2 + (\za)^2) });
\addplot[name path=A4, domain=0:1, samples=100, draw=black, line width=1pt]
({ (\xb)/sqrt((\xb)^2 + ((1 - x)*\ya + x*\yb)^2 + (\za)^2) },
{ ((1 - x)*\ya + x*\yb)/sqrt((\xb)^2 + ((1 - x)*\ya + x*\yb)^2 + (\za)^2) });
\renewcommand{\za}{1}
\addplot[name path=B1, domain=0:1, samples=100, draw=black, line width=1pt]
({ ((1 - x)*\xa + x*\xb)/sqrt(((1 - x)*\xa + x*\xb)^2 + (\ya)^2 + (\za)^2) },
{ (\ya)/sqrt(((1 - x)*\xa + x*\xb)^2 + (\ya)^2+ (\za)^2) });
\addplot[name path=B2, domain=0:1, samples=100, draw=black, line width=1pt]
({ ((1 - x)*\xa + x*\xb)/sqrt(((1 - x)*\xa + x*\xb)^2 + (\yb)^2 + (\za)^2) },
{ (\yb)/sqrt(((1 - x)*\xa + x*\xb)^2 + (\yb)^2 + (\za)^2) });
\addplot[name path=B3, domain=0:1, samples=100, draw=black, line width=1pt]
({ (\xa)/sqrt((\xa)^2 + ((1 - x)*\ya + x*\yb)^2 + (\za)^2) },
{ ((1 - x)*\ya + x*\yb)/sqrt((\xa)^2 + ((1 - x)*\ya + x*\yb)^2 + (\za)^2) });
\addplot[name path=B4, domain=0:1, samples=100, draw=black, line width=1pt]
({ (\xb)/sqrt((\xb)^2 + ((1 - x)*\ya + x*\yb)^2 + (\za)^2) },
{ ((1 - x)*\ya + x*\yb)/sqrt((\xb)^2 + ((1 - x)*\ya + x*\yb)^2 + (\za)^2) });
\path[name path=A13, intersection segments={of=A1 and A3, sequence={L*[reverse] -- R*}}];
\path[name path=A24, intersection segments={of=A2 and A4, sequence={L* -- R*[reverse]}}];
\fill[green!20, draw=black, intersection segments={of=A13 and A24, sequence={L* -- R*}}] -- cycle;
\end{axis}
\end{tikzpicture}
\end{document}
定义函数以避免重复代码可能是一个好主意。此外,在全局级别定义名称非常短的宏可能会与其他包或命令发生冲突。
这是一个使用先前定义的函数的解决方案,这样就避免了在全局级别定义命令的需要。输出与上面相同。
\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\pgfplotsset{compat=1.18}
\begin{document}
\begin{tikzpicture}[scale=1]
\begin{axis}[
axis equal,
hide axis,
/pgf/declare function = {
xa = 0.1;
xb = 0.7;
ya = 0.8;
yb = -0.2;
zx = 0.5;
zy = 1;
fa(\a,\b,\c,\d) = ((1 - x)*\a + x*\b)/sqrt(((1 - x)*\a + x*\b)^2 + (\c)^2 + (\d)^2);
fb(\a,\b,\c,\d) = (\a)/sqrt(((1 - x)*\b + x*\c)^2 + (\a)^2 + (\d)^2);
fc(\a,\b,\c,\d) = (\a)/sqrt((\a)^2 + ((1 - x)*\b + x*\c)^2 + (\d)^2);
fd(\a,\b,\c,\d) = ((1 - x)*\a + x*\b)/sqrt((\c)^2 + ((1 - x)*\a + x*\b)^2 + (\d)^2);
}
]
\addplot[name path=A1, domain=0:1, samples=100, draw=black, line width=1pt]
({ fa(xa,xb,ya,zx) }, { fb(ya,xa,xb,zx) });
\addplot[name path=A2, domain=0:1, samples=100, draw=black, line width=1pt]
({ fa(xa,xb,yb,zx) }, { fb(yb,xa,xb,zx) });
\addplot[name path=A3, domain=0:1, samples=100, draw=black, line width=1pt]
({ fc(xa,ya,yb,zx) }, { fd(ya,yb,xa,zx) });
\addplot[name path=A4, domain=0:1, samples=100, draw=black, line width=1pt]
({ fc(xb,ya,yb,zx) }, { fd(ya,yb,xb,zx) });
\addplot[name path=B1, domain=0:1, samples=100, draw=black, line width=1pt]
({ fa(xa,xb,ya,zy) }, { fb(ya,xa,xb,zy) });
\addplot[name path=B2, domain=0:1, samples=100, draw=black, line width=1pt]
({ fa(xa,xb,yb,zy) }, { fb(yb,xa,xb,zy) });
\addplot[name path=B3, domain=0:1, samples=100, draw=black, line width=1pt]
({ fc(xa,ya,yb,zy) }, { fd(ya,yb,xa,zy) });
\addplot[name path=B4, domain=0:1, samples=100, draw=black, line width=1pt]
({ fc(xb,ya,yb,zy) }, { fd(ya,yb,xb,zy) });
\path[name path=A13, intersection segments={of=A1 and A3, sequence={L*[reverse] -- R*}}];
\path[name path=A24, intersection segments={of=A2 and A4, sequence={L* -- R*[reverse]}}];
\fill[green!20, draw=black, intersection segments={of=A13 and A24, sequence={L* -- R*}}] -- cycle;
\end{axis}
\end{tikzpicture}
\end{document}