填充抛物线与多条线之间的区域

填充抛物线与多条线之间的区域

我有一条抛物线和 4 条线。我需要做的是填充抛物线和这些线所界定的外部区域。这是我目前拥有的 1]

我希望橙色填充仅位于由线段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。简而言之:LR代表与给定的路径相对应的“左”和“右” 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}

该图显示了上述代码的结果

相关内容