4

I would like to fill an area between two Bezier curves.

 \documentclass{minimal}
 \usepackage{tikz}
 \usetikzlibrary{arrows, calc, shapes}

 \usepackage{pgfplots}
 \pgfplotsset{compat=1.10}
 \usepgfplotslibrary{fillbetween}

 \begin{document}
 \begin{tikzpicture}

 \draw[name path=A] (1cm,4cm) .. controls (1.3cm,1.2cm) and (1.5cm,1cm) .. (10cm,0.4cm);
 \draw[name path=B] (1cm,-4cm) .. controls (1.3cm,-1.2cm) and (1.5cm,-1cm) .. (10cm,-0.4cm);


 \end{tikzpicture}

I've already tried it with \filldraw, but unfortunately this keeps filling the wrong side. I've also considered the possibility to use \addplot[brown!50] fill between[of=A and B]; , but I struggeled to add the Bezier Curves with the \addplot command.

Also I'd like to have a opacity flow from left to right.

3

4 Answers 4

5

Without using any additional libraries, you may just use the clipping function (and store the path in a macro for convenience):

\documentclass[tikz]{standalone}
\usetikzlibrary{intersections}

\begin{document}

 \begin{tikzpicture}
  \newcommand{\pathA}{(1cm,4cm) .. controls (1.3cm,1.2cm) and (1.5cm,1cm) .. (10cm,0.4cm)}
  \newcommand{\pathB}{(1cm,-4cm) .. controls (1.3cm,-1.2cm) and (1.5cm,-1cm) .. (10cm,-0.4cm)}

  \begin{scope}
   \clip \pathA -- (10cm,-4cm) -- (1cm,-4cm) -- cycle; 
   \fill[orange!50] \pathB -- (10cm,4cm) -- (1cm,4cm) -- cycle;
  \end{scope}

  \draw \pathA;
  \draw \pathB;

 \end{tikzpicture}

\end{document}

enter image description here

0
3

I am wondering it you are referring to the trick discussed here and used in this answer, where it is described how the intersection library can be used to essentially combine two paths to a new path. Using this trick, one can actually get the desired filling in two steps. This leads to the code

\documentclass[margin=5mm,tikz]{standalone}
\usetikzlibrary{intersections}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
% based on https://tex.stackexchange.com/a/302531/121799
% and http://texwelt.de/wissen/fragen/4153/wie-kann-ich-die-flache-zwischen-mehreren-pfaden-fullen/4161s
\begin{document} 
\begin{tikzpicture}
  \pgfdeclarelayer{pre main}
  \pgfsetlayers{pre main,main}
  \draw [name path=A] (1cm,4cm) .. controls (1.3cm,1.2cm) and (1.5cm,1cm) ..
     (10cm,0.4cm);
  \draw [name path=B] 
    (1cm,-4cm) .. controls (1.3cm,-1.2cm) and (1.5cm,-1cm)
     .. (10.cm,-0.4cm);
  \path [name path=C] (1cm,4cm) -- (1cm,-4cm); 
  \path [name path=D] (10cm,-0.4cm) -- (10cm,0.4cm); 
  \path [%draw,line width=3,blue,
    name path=AandC,
    intersection segments={
        of=A and C,
        sequence={A1[reverse] -- B1}
    }];
  \path [%draw,line width=3,purple,
    name path=BandD,
    intersection segments={
        of=B and D,
        sequence={A0 -- B1[reverse]}
   }];

  \pgfonlayer{pre main}
  \fill [
    blue!40!white,
    intersection segments={
        of=AandC and BandD,
        sequence={A1 -- B1},
    }
  ];
  \endpgfonlayer

\end{tikzpicture} 
\end{document}

enter image description here

WARNING: I kept your path labels, but want to draw your attention to the fact that A and B in sequence={A1[reverse] -- B1} and sequence={A1 -- B1} does not refer to these paths. Rather, A and B refer to the two paths that are being married. (What [reverse] does is more intuitive.) The numbers after A and B (seem to) refer to the part that should be put in this path, e.g. A0 is the stretch of the first path before the intersection and A1 is the stretch after. Once you know this, this might be the most straightforward way of combining paths, and use those for shading etc. (Of course, in order to make this work, I needed to add the vertical paths at boundaries, C and D.)

3

(I know this is an old post but it's just resurfaced ...)

I'm a bit surprised that the following solution hasn't been suggested already: simply join the paths with lines and shade (or fill) the region thus defined.

\documentclass{article}
%\url{https://tex.stackexchange.com/q/417970/86}
 \usepackage{tikz}

 \begin{document}
 \begin{tikzpicture}

\shade[left color=brown!50]
(1cm,4cm) .. controls (1.3cm,1.2cm) and (1.5cm,1cm) .. (10cm,0.4cm)
--
(10cm,-0.4cm) .. controls (1.5cm,-1cm) and (1.3cm,-1.2cm)  .. 
(1cm,-4cm) -- cycle;

 \draw (1cm,4cm) .. controls (1.3cm,1.2cm) and (1.5cm,1cm) .. (10cm,0.4cm);
 \draw (1cm,-4cm) .. controls (1.3cm,-1.2cm) and (1.5cm,-1cm) .. (10cm,-0.4cm);


 \end{tikzpicture}
 \end{document}

The only down side of this is defining the paths twice. In this case, they aren't very complicated so that doesn't seem a hardship. If that is a problem, then the following uses spath3 to save and reuse the paths.

\documentclass{article}
%\url{https://tex.stackexchange.com/q/417970/86}
 \usepackage{tikz}

\usetikzlibrary{spath3}

 \begin{document}
 \begin{tikzpicture}

% Save the paths, but don't draw them
 \path[spath/save=A] (1cm,4cm) .. controls (1.3cm,1.2cm) and (1.5cm,1cm) .. (10cm,0.4cm);
 \path[spath/save=B] (1cm,-4cm) .. controls (1.3cm,-1.2cm) and (1.5cm,-1cm) .. (10cm,-0.4cm);

\shade[
  left color=brown!50,
  spath/use=A % set the initial path to be A
]
-- (spath cs:B 1) % add a straight line to the end of B
[spath/use={B,reverse,weld}] % append path B, reversing it, and welding it
% to make a single path for shading
-- cycle % cycle back to the start
;

\draw[spath/use=A]; % draw path A
\draw[spath/use=B]; % draw path B

 \end{tikzpicture}
 \end{document}

Both of these produce the following:

Shaded region between two paths

4
2

I guess that what you want is filling with given left color and given right color. For TikZ, with simplifying path operations, we use a small trick to do that.

enter image description here

\documentclass[border=5mm,tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\def\pathA{(1,4) .. controls (1.3,1.2) and (1.5,1) .. (10,0.4)}
\def\pathB{(1,-4) .. controls (1.3,-1.2) and (1.5,-1) .. (10,-0.4)}

% this is a small trick: clip a bigger region to fill       
\begin{scope}
\clip \pathA -- (10,-4) -- (1,-4) -- cycle; 
\fill[left color=orange,right color=orange!50] \pathB -- (10,4) -- (1,4) -- cycle;
\end{scope}
        
\draw[blue] \pathA;
\draw[red] \pathB;
\end{tikzpicture}
\end{document}

For Asymptote, with many path operations, this is straight to do that: reverse to reverse a path; relpoint to pick a point on a path. To fill with an uniform color, use fill(mypath,orange);. There are several other kinds of filling: axialshade, radialshade, gouraudshade, tensorshade, functionshade see here.

enter image description here

// http://asymptote.ualberta.ca/
unitsize(1cm);
path pA=(1,4) .. controls (1.3,1.2) and (1.5,1) .. (10,0.4);
path pB=(1,-4) .. controls (1.3,-1.2) and (1.5,-1) .. (10,-0.4);
// path pB=yscale(-1)*pA;    // <<< also works!
path mypath=pA--relpoint(pB,1)--reverse(pB)--cycle;

// fill with uniform color
//fill(mypath,orange);

// fill with left and right color
pen leftpen=green;
pen rightpen=.1green+white;
axialshade(mypath,leftpen,(0,0),rightpen,(10,0));

draw(pA,blue);
draw(pB,red);
shipout(bbox(5mm,invisible));

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .