我有一条抛物线和 4 条线。我需要做的是填充抛物线和这些线所界定的外部区域。这是我目前拥有的
我希望橙色填充仅位于由线段AH
和界定的矩形内AB
。
我尝试过裁剪填充,但没有成功。我使用的是 PGFplots。这是我当前的相关代码
\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.11}
\usepgfplotslibrary{fillbetween}
% axis style, ticks, etc
\pgfplotsset{every axis/.append style={
axis x line=middle, % put the x axis in the middle
axis y line=middle, % put the y axis in the middle
axis line style={<->}, % arrows on the axis
xlabel={$x$}, % default put x on x-axis
ylabel={$y$}, % default put y on y-axis
axis equal, % 1:1 ratio
grid=both, % coordinate grid
grid style={line width=.1pt, draw=gray!10},
major grid style={line width=.2pt,draw=gray!50},
ticks=both, % ticks for integers
minor tick num=5, % number of subticks
ticklabel style={font=\small,fill=white},
xlabel style={at={(ticklabel* cs:1)},anchor=north west},
ylabel style={at={(ticklabel* cs:1)},anchor=south west},
}
}
\tikzset{>=stealth}
\begin{document}
\begin{center}
\begin{tikzpicture}
\begin{axis}[xmin=-1.5,ymin=-1,xmax=2.5,ymax=6]
\coordinate (O) at (0,0);
\node[fill=white,circle,inner sep=0pt] (O-label) at ($(O)+(-35:10pt)$) {$O$};
\coordinate (A) at (-1.12,1.24);
\LabelPoint[mark=*][above right]{-1.09}{1.18}{$A$}
\coordinate (B) at (-1.4,1.96);
\LabelPoint[mark=*][above right]{1.4}{1.96}{$B$}
\coordinate (H) at (-0.63,-0.21);
\LabelPoint[mark=*][below left]{-0.63}{-0.21}{$H$}
\addplot[name path = f,red,thick,samples=500] {x^2};
\addplot[name path = l1,thick] {1/3*x+1.5};
\addplot[name path = l2,thick] {1/3*x};
\addplot[name path = p1,thick,green] {-3*x-2.1};
\addplot[name path = p2,thick,green] {-3*x+6.2};
\addplot [
thick,
color=blue,
fill=none,
fill opacity=0.5
]
fill between[
of=f and l1,
split,
every segment no 1/.style={
fill=blue,
},
];
\clip (A) -- (B) -- (1.86,0.62) -- (H) -- cycle;
\clip[domain=-1.5:2] plot (\x,{\x^2}) -- (2,0) -- (-1.5,0) -- cycle;
\addplot[
thick,
color=orange,
fill=orange,
fill opacity=0.5
]
fill between[
of=f and l2,
soft clip={domain=-1.12:1.86}
];
\end{axis}
\end{tikzpicture}
\end{center}
\end{document}
(\LabelPoint
仅在给定的坐标处做一个标记并放置一个带有一些文本的节点)。
无论是否剪辑,结果都保持不变。我对 PGF 还很陌生,我之前只用 Tikz 就有一个解决方案,但看起来很糟糕,我很好奇想尝试用 PGF 来制作图表。
有没有通用的方法来处理 2 个以上地块之间的填充区域?这种一般情况适用于此处吗?
谢谢你的帮助。
答案1
所以这就是你要找的。有关详细信息,请查看代码中的注释。诀窍是绘制二橙色填充物,即左边一份,右边一份。
为此,我使用了intersection segments
功能(大致相当于 TikZ 中的 PGFPlots fill between
)。然后sequence
允许我们绘制给定的两条路径的任意路径of
。简而言之:L
和R
代表与给定的路径相对应的“左”和“右” of
。数字指的是路径元素。1
表示“从起点到第一个交叉点”,2
表示“从第一个交叉点到第二个交叉点”,等等。
(我在代码末尾添加了一些注释的“调试”代码和一些描述。试一次,你就会很容易地发现它是如何工作的。不幸的是,有时还会有一些“魔法”留存,就像这个例子中的那样。)
% used PGFPlots v1.15
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{
calc,
pgfplots.fillbetween,
}
\tikzset{>=stealth}
\pgfplotsset{
compat=1.11,
every axis/.append style={
axis x line=middle,
axis y line=middle,
axis line style={<->},
xlabel={$x$},
ylabel={$y$},
axis equal,
grid=both,
grid style={line width=.1pt, draw=gray!10},
major grid style={line width=.2pt,draw=gray!50},
ticks=both,
minor tick num=5,
ticklabel style={font=\small,fill=white},
xlabel style={at={(ticklabel* cs:1)},anchor=north west},
ylabel style={at={(ticklabel* cs:1)},anchor=south west},
},
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
xmin=-1.5,
ymin=-1,
xmax=2.5,
ymax=6,
% to be able to draw the orange filling on another layer
set layers,
]
% draw the function and the "intersection lines"
% (please note that I have changed the number of samples and added
% the option `smooth' to avoid some numerical instabilities for `f')
\addplot [name path=f,red,thick,samples=49,smooth] {x^2};
\addplot [name path=l1,thick] {1/3*x+1.5};
\addplot [name path=l2,thick] {1/3*x};
\addplot [name path=p1,thick,green] {-3*x-2.1};
\addplot [name path=p2,thick,green] {-3*x+6.2};
% find the intersection points of the black and green lines
\path [
name intersections={
of=l1 and p1,
by={A},
},
];
\path [
name intersections={
of=l1 and p2,
by={B},
},
];
\path [
name intersections={
of=l2 and p2,
by={C},
},
];
\path [
name intersections={
of=l2 and p1,
by={H},
},
];
% create coordinate at origin
\coordinate (O) at (0,0);
% create invisible clip paths which are needed for the orange filling
\path [name path=clippath1] (A) -- (H) -- (C) -- cycle;
\path [name path=clippath2] (O) -- (C) -- (B) -- cycle;
% draw the intersection points
\pgfmathsetlengthmacro{\Radius}{2pt}
\fill
(A) circle (\Radius)
(B) circle (\Radius)
(C) circle (\Radius)
(H) circle (\Radius)
;
% label the intersection points
\node [coordinate,label=below right:$O$] at (O) {};
\node [coordinate,label=above right:$A$] at (A) {};
\node [coordinate,label=above right:$B$] at (B) {};
\node [coordinate,label=below right:$C$] at (C) {};
\node [coordinate,label=below left:$H$] at (H) {};
% fill the area between the intersection points on a lower layer
% so the red function line doesn't have to be plotted twice
\begin{pgfonlayer}{axis ticks}
% left half
\fill [
orange,
fill opacity=0.5,
% (this is the TikZ equivalent to PGFPlots `fill between')
intersection segments={
of=f and clippath1,
% (here we can draw -- in general -- an arbitrary path
% between the path elements of intersection points.
% Of course here we want to find the path that surrounds
% the area that we want to fill.)
sequence={R1[reverse] -- L2},
},
];
% right half
\fill [
orange,
fill opacity=0.5,
intersection segments={
of=f and clippath2,
sequence={R{-2} -- L{-2}[reverse]},
},
];
\end{pgfonlayer}
% draw the blue filling
\addplot [
fill=none,
] fill between [
of=f and l1,
split,
every segment no 1/.style={
fill=blue,
fill opacity=0.5,
},
];
% % ---------------------------------------------------------------------
% % for debugging purpose only
% % ---------------------------------------------------------------------
% % To find the right `sequence' you can play with the elements.
% % Just start with one single element like `R1' to see what happens and
% % then replace them until you found the right ones and connect them in
% % the right order.
% \draw [
% blue,
% very thin,
% |->,
% intersection segments={
% of=f and clippath1,
% sequence={
% % Because we know that the "green/black" line is needed
% % from the start to the first intersection point, for sure
% % we need `R1'.
% % And we also know that we need for the "red" line the part
% % from the first (not real) intersection point above (left)
% % of point A (crossing of the green and red line) to the
% % second intersection point (at point O)
% % (There is still some magic left why there is this "not
% % real" intersection point ...)
% R1[reverse] -- L2
%% % so the reverse path is also fine, which can be done by
%% % reversing the "pathes" ...
%% R1 -- L2[reverse]
%% % ... or the elements of the pathes which offers another
%% % two possibilities to do this
%% L2 -- R1[reverse]
%% L2[reverse] -- R1
%% % Another possibility to avoid the `[reverse] you could
%% % simply reverse the path directly `clippath1' from
%% % (A) -- (H) -- (C) -- cycle
%% % to
%% % (C) -- (H) -- (A) -- cycle
%% % in the (above) definition of that path.
%% % Can you imagine how the right elements and sequence is then?
%% % (One tip: It is not as simple as `L2 -- R1')
% },
% },
% ];
% \draw [
% blue,
% very thin,
% |->,
% intersection segments={
% of=f and clippath2,
% sequence={
%% % try to find the right elements and orders here yourself
% R{-1}
% },
% },
% ];
% % ---------------------------------------------------------------------
\end{axis}
\end{tikzpicture}
\end{document}