0

I am trying to fill the outside of the intersection between 2 curves, using fillbetween option in TikZ. This drawing is a part of a more complicated picture; so I prefer to use my curve definition code. I do not want to use \addplot, so that I can control the shape of the curves as needed.

Inspired by the answer of Jasper Habicht to this post, I came up with the following code to manually fill the designated area. This approach draws a straight-lines triangular area.

To follow the curvature of the curves, is there a way to fill this area, for example using the code: intersection segments={of=curveA and topAB and curveB}; or using soft clip.

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\usetikzlibrary{backgrounds,shadings,patterns}
\begin{document}
\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){};}}}
%
\tikzset{lw/.style={line width=.08cm}}
%
\begin{tikzpicture}[scale=.8, 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) to [out=55, in=160, looseness=.68] node[pos=.1] (mda){} 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]node[pos=.1] (mdb){} (end.center) to [out=-20, in=174, looseness=1.] (endr.center) --  ([shift={(0.:.8cm)}]endr.center);
%
\path[name path=topAB] (mda.center) --  (mdb.center);
%
\path[name intersections={of=curveA and curveB}] (intersection-2) node[circle, black, fill=black, scale=0.6] (ab2) {};
%
\begin{scope}[on background layer]
\path[fill=red!50] (ab2.center) -- ([shift={(0.:.14cm)}]mda.center) -- ([shift={(180.:.14cm)}]mdb.center) -- cycle;
\end{scope}
\end{tikzpicture}
\end{document}

enter image description here

1
  • I still would suggest that you use \coordinates and not nodes if you only need to identify certain positions in your diagram. Nodes have a shape as well as an outer and inner sep whch you might need to take into account. If using coordinates, you don't need to select .center as anchor. If you use pgfplots, consider setting \pgfplotsset{compat=newest}. Also, there is no need to escape line ends or empty lines using % inside a tikzpicture environment. Commented Jun 5, 2023 at 6:22

2 Answers 2

1

Well, if you know the coordinates that sit at the maxima of the two curves, you can do as follows (I changed some nodes to coordinates in the \pic and the curve defintions, but this does not change anything for the outcome; the relevant stuff are the paths on the background layer):

\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}
\pgfplotsset{compat=newest}
\usetikzlibrary{backgrounds}

\begin{document}
\tikzset{pics/.cd,
    curvef/.style n args={2}{code={
        \coordinate (begin) at (#1,#2);
        \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);
    }
}}

\tikzset{lw/.style={line width=.08cm}}

\begin{tikzpicture}[scale=.8, transform shape]

\pic at (0,0) {curvef={.8}{0}};

\draw[blue, lw, name path=curveA]
    ([shift={(180.:.8cm)}]begin) --
    (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=.1] (mda) 
    coordinate [pos=.74] (r) 
    (end) to [out=-20, in=174, looseness=1.] 
    (endr) --
    ([shift={(0.:2.6cm)}]endr);

\pic at (2,0) {curvef={.8}{0}};

\draw[green!60!black, lw, name path=curveB] 
    ([shift={(180.:2.8cm)}]begin) -- 
    (begin) to [out=6, in=-160, looseness=1.] 
    (beginr) to [out=20, in=-125, looseness=.68] 
    (midtop) coordinate (mdb) 
    to [out=55, in=160, looseness=.68] 
    coordinate [pos=.1] (mdb)
    (end) to [out=-20, in=174, looseness=1.] 
    (endr) --  
    ([shift={(0.:.8cm)}]endr);

\path[name intersections={of=curveA and curveB}] 
    (intersection-2) node[circle, black, fill=black, scale=0.6] (ab2) {};

\begin{scope}[on background layer]
    \path[fill=red!50, name path=layerAB] 
        (ab2.center) -| (mda) -- (mdb) |- cycle;
    
    \path[name path=layerABtemp, intersection segments={
            of=curveA and layerAB, sequence={L2[reverse] -- R3}
        }] -- cycle;

    \path[fill=red, intersection segments={
            of=layerABtemp and curveB, sequence={L2 -- R2[reverse]}
        }] -- cycle;
\end{scope}

\end{tikzpicture}
\end{document}

enter image description here

Note that it is not necessary to escape blank lines or lines ends inside a tikzpicture. Also, I would suggest that you use \coordinates instead of nodes where possible, because this simplifies your code (you don't need to use the .center anchor, for example) and also, nodes have inner and outer seps which might affect the output.

If you load pgfplots (which is necessary for the fillbetween library, you don't need to load tikz separately. But when using pgfplots, make sure to alsways set the compat opton so something reasonable.

4
  • @ Jasper Habicht Thank you very much for your answer and comments, which I appreciate very much. My drawings are used in different locations and in other documents as well. This is just only an MWE. The original drawings contain many other elements. In many situations, the nodes include circles, for example. That is why in tikzset codes for some curves, which are repeatedly used with different added other elements, I use nodes instead of coordinates. I usually use coordinates for elements which do not need such additions.
    – Hany
    Commented Jun 5, 2023 at 10:03
  • I use % on empty lines, because some answers, to my previous posts, suggest that I have to leave empty lines between different code lines for easier identification of them. I intentionally mark those empty lines with %, so that I can avoid missing them during preparing the post. As you know, 4 spaces have to be inserted at the beginning of each line.
    – Hany
    Commented Jun 5, 2023 at 10:05
  • @Hany Sure, in certain cases, your use of syntax might be totally reasonable. I hope that my answer is still helpful to you! Commented Jun 5, 2023 at 18:00
  • @ Jasper Habicht Certainly, your answer, comments, and explanations are very useful. I appreciate them very much. Thank you.
    – Hany
    Commented Jun 6, 2023 at 3:41
1

Here is a trick with TikZ.

enter image description here

\documentclass[tikz,border=5mm]{standalone}
\begin{document}
\begin{tikzpicture}[thick]
\def\Aleft{(-3,0)--(-2,0) .. controls +(0:2) and +(180:.3) ..(0,2)}
\def\Aright{(0,2) .. controls +(0:.3) and +(180:2) .. (2,0)--(3,0)}
\def\Bleft{[shift={(-1,0)}]\Aleft}
\def\Bright{[shift={(-1,0)}]\Aright}
\def\curveA{\Aleft--\Aright}
\def\curveB{[shift={(-1,0)}]\curveA}
\begin{scope}
\clip \Aleft -|  cycle;
\clip \Bright |- cycle;
\fill[yellow] (0,2) rectangle +(-1,-2);
\end{scope}
\draw[blue] \curveA;
\draw[teal] \curveB;
\end{tikzpicture}
\end{document}  
3
  • @ Black Mild Thank you for your suggestion. But, as I`ve mentioned, I need to fill the designated area for other curves with different settings. So, I can not modify all my curves to apply your suggestion. Each curve has a meaning for its orientation; and your curves does not match these specifications. So, I need a solution that can also be applied for other situations.
    – Hany
    Commented Jun 5, 2023 at 4:08
  • ThenI suggest to add a foto, drawing, scan or some other sketch of your curve ensembles to your question to make your requirements more visible. Thanks
    – MS-SPO
    Commented Jun 5, 2023 at 5:18
  • @ MS-SPO I have to include the code which produce the drawings to clarify my ideas and needs, so that they can be reproduced by those who would answer my question. So, why do I insert a photo when I can include the output picture itself!
    – Hany
    Commented Jun 5, 2023 at 9:50

You must log in to answer this question.

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