5

I am trying to fill the space between two curves created by the hobby library. I tried the method mentioned in this post, however, it did not succeed. Can someone help me out? Thx

\documentclass{standalone}

\usepackage{tikz,pgfplots}
\usetikzlibrary{decorations.shapes}
\usetikzlibrary{hobby}
\usetikzlibrary{calc}
\usepgfplotslibrary{fillbetween}
\usetikzlibrary{intersections}

\begin{document}

\begin{tikzpicture}[scale=1, use Hobby shortcut]

 \draw[name path = A]
  (3.18, 1.05)..
  (2.7,.58)..
  (2.45,-.95)..
  (1.81,-1.35)
  ;
 \draw[name path = B]
  (3.18, 1.05)..
  (1.73,1.01)..
  (0,.57)..
  (-1.07,0)..
  (-1.43, -.26)..
  (-1.76,-.61)..
  (-1.81,-.89)..
  (-1.56,-.91)..
  (-.95, -.78)..
  (0,-.66)..
  (.79,-.7)..
  (1.23,-.88)..
  (1.81,-1.35)
  ;
  % \path[name intersections={of=A and B,by={a,b}}];
  % \begin{scope}
  %   \clip (a) rectangle ([xshift=-2cm]b);
  %   \filldraw[fill=green]
  %   (2,2) circle (3cm);
  % \end{scope}

\end{tikzpicture}
\end{document}

3 Answers 3

4

This is Kpym's idea of using my spath3 library. Originally (at time of first writing) this needed a few internal commands to be promoted to user-level. Thanks to prompting by Kpym, I've implemented this properly and the update has now made its way to CTAN and to the TeXLive repositories.

Here are two ways to achieve this using the spath3 library. One saves the two paths separately and then combines them in a third command. The second saves one of the paths and then inserts it after the second. The output is the same in both cases.

\documentclass{article}
%\url{https://tex.stackexchange.com/q/484027/86}
\usepackage{tikz}
\usetikzlibrary{hobby, calc, spath3}

\begin{document}

\begin{tikzpicture}[use Hobby shortcut]
 \path[spath/save = A]
  (3.18, 1.05)..
  (2.7,.58)..
  (2.45,-.95)..
  (1.81,-1.35)
  ;
 \path[spath/save = B]
  (3.18, 1.05)..
  (1.73,1.01)..
  (0,.57)..
  (-1.07,0)..
  (-1.43, -.26)..
  (-1.76,-.61)..
  (-1.81,-.89)..
  (-1.56,-.91)..
  (-.95, -.78)..
  (0,-.66)..
  (.79,-.7)..
  (1.23,-.88)..
  (1.81,-1.35)
  ;

\filldraw[
  fill=blue,
  draw=black,
  ultra thick,
  spath/restore=A
]
[spath/append reverse=B]
-- cycle;
\end{tikzpicture}

\begin{tikzpicture}[use Hobby shortcut]

 \path[overlay,spath/save = A]
  (3.18, 1.05)..
  (2.7,.58)..
  (2.45,-.95)..
  (1.81,-1.35)
  ;


\filldraw[fill=blue, draw=black, ultra thick]
  (3.18, 1.05)..
  (1.73,1.01)..
  (0,.57)..
  (-1.07,0)..
  (-1.43, -.26)..
  (-1.76,-.61)..
  (-1.81,-.89)..
  (-1.56,-.91)..
  (-.95, -.78)..
  (0,-.66)..
  (.79,-.7)..
  (1.23,-.88)..
  ([Hobby finish]1.81,-1.35) % needed to trigger hobby path generation before adding the new path
[spath/append reverse=A] -- cycle
  ;
\end{tikzpicture}
\end{document}

reversed and filled path

3

You are loading pgfplots and its library fillbetween, so you may also want to use them. The challenge is sometimes to find the relevant segments since it so happens that TikZ finds "too many" intersection points. Another remark concerns the fact that here you do not need this, you could just revert the ordering of the coordinates in one of the paths and patch them together (right figure).

\documentclass{standalone}
\usepackage{tikz,pgfplots}
\pgfplotsset{compat=1.16}
\usetikzlibrary{hobby}
\usepgfplotslibrary{fillbetween}

\begin{document}

\begin{tikzpicture}[scale=1, use Hobby shortcut]

 \draw[name path=A]
  (3.18, 1.05)..
  (2.7,.58)..
  (2.45,-.95)..
  (1.81,-1.35)
  ;
 \draw[name path=B]
  (3.18, 1.05)..
  (1.73,1.01)..
  (0,.57)..
  (-1.07,0)..
  (-1.43, -.26)..
  (-1.76,-.61)..
  (-1.81,-.89)..
  (-1.56,-.91)..
  (-.95, -.78)..
  (0,-.66)..
  (.79,-.7)..
  (1.23,-.88)..
  (1.81,-1.35)
  ;
  \path[%draw=red,
  fill=blue,intersection segments={of=A and B,
 sequence={L2[reverse]--R2}}];
\begin{scope}[xshift=5cm]
 \draw[fill=blue] (3.18, 1.05)..
  (1.73,1.01)..
  (0,.57)..
  (-1.07,0)..
  (-1.43, -.26)..
  (-1.76,-.61)..
  (-1.81,-.89)..
  (-1.56,-.91)..
  (-.95, -.78)..
  (0,-.66)..
  (.79,-.7)..
  (1.23,-.88)..
  (1.81,-1.35)
  (1.81,-1.35)..
  (2.45,-.95)..
  (2.7,.58)..
  (3.18, 1.05);
\end{scope}
\end{tikzpicture}
\end{document}

enter image description here

3

Since the end points of your paths are identical, you can save both paths, reverse one of them and combine them to fill in between.

The best solution is probably to use the `spath3' library which contains everything you need, but I don't know how to reverse the paths using this library :(

So in view of my ignorance I created the following code to save and reverse paths using show path construction based on this answer.

\documentclass[varwidth,border=7pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing}
\tikzset{
  store savedtikzpath in/.code=\xdef#1{\savedtikzpath},
  append tikz path/.style = {
    decoration={show path construction,
      moveto code=\xdef\savedtikzpath{\savedtikzpath (\tikzinputsegmentfirst)},
      lineto code=\xdef\savedtikzpath{\savedtikzpath -- (\tikzinputsegmentlast)},
      curveto code=\xdef\savedtikzpath{\savedtikzpath .. controls%
        (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb) ..(\tikzinputsegmentlast)},
      closepath code=\xdef\savedtikzpath{\savedtikzpath -- cycle}
    },
    decorate,
    postaction = {store savedtikzpath in=#1}
  },
  prepend reversed tikz path/.style = {
    decoration={show path construction,
      moveto code=\xdef\savedtikzpath{(\tikzinputsegmentfirst) \savedtikzpath},
      lineto code=\xdef\savedtikzpath{(\tikzinputsegmentlast) -- \savedtikzpath},
      curveto code=\xdef\savedtikzpath{(\tikzinputsegmentlast) .. controls%
        (\tikzinputsegmentsupportb) and (\tikzinputsegmentsupporta) .. \savedtikzpath},
      closepath code=\xdef\savedtikzpath{\savedtikzpath -- cycle}
    },
    decorate,
    postaction = {store savedtikzpath in=#1}
  },
  append tikz path/.default = \savedtikzpath,
  save tikz path/.style = {append tikz path=#1},
  save tikz path/.prefix code={\xdef\savedtikzpath{}},
  save reversed tikz path/.style = {prepend reversed tikz path=#1},
  save reversed tikz path/.prefix code={\xdef\savedtikzpath{}},
}
\usetikzlibrary{hobby}
\begin{document}
  \begin{tikzpicture}[use Hobby shortcut]
    \path[save tikz path=\pathA] (3.18, 1.05).. (2.7,.58).. (2.45,-.95).. (1.81,-1.35);
    \path[save reversed tikz path=\pathB] (3.18, 1.05).. (1.73,1.01).. (0,.57).. (-1.07,0).. (-1.43, -.26).. (-1.76,-.61).. (-1.81,-.89).. (-1.56,-.91).. (-.95, -.78).. (0,-.66).. (.79,-.7).. (1.23,-.88).. (1.81,-1.35);
    \filldraw[ultra thick, red,fill=blue] \pathA -- \pathB -- cycle;
  \end{tikzpicture}
\end{document}

enter image description here

You must log in to answer this question.

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