1

I am trying to draw what you see in the figure, a smooth surface with another embedded surface that has sharp corners. I'm using the hobby package and this is what I have so far. The problem is that as you can see, the inner surface is not really fitting properly within the outer surface (see top and bottom in the figure) and I have already spent way too much time fiddling with the coordinates and the controls to make me ask whether there is a better way (faster, more efficient) way to do this. This is the MWE:

\documentclass{standalone}

\usepackage{tikz}
\usepackage{xcolor}
\usetikzlibrary{calc,hobby,positioning,patterns,decorations.pathreplacing,arrows.meta} % To draw the smooth curve

\tikzset{% adapted from hobby_doc.tex
  show curve controls/.style={
    decoration={
      show path construction,
      curveto code={
        \draw [blue, -{Circle[black,open]}] (\tikzinputsegmentfirst) -- (\tikzinputsegmentsupporta) ;
        \draw [blue, {Circle[black,open]}-] (\tikzinputsegmentsupportb) -- (\tikzinputsegmentlast) ;
      }
    },decorate
  },
}


\begin{document}

\begin{tikzpicture}

\begin{scope} [rotate=0,yscale=-1.5,xscale=1.5]
\coordinate (b1) at (3.5392,1.208);
\draw[use Hobby shortcut, thick, fill=gray!5] ([out angle=-90]b1)..(3.2677,0.7067)..(2.0238,0.3988)..(0.4235,1.9163)..(0.4036,2.3412)..(1.2469,3.8406)..(2.5315,3.3503)..(2.7711,2.2784)..(3.2214,1.7665)..([in angle=90]b1);

\coordinate (A) at (1.7662,0.4514);
\coordinate (B) at (1.1987,0.7091);
\coordinate (C) at (0.8485,2.1671);
\coordinate (D) at (0.8033,3.5137);
\coordinate (E) at (1.2038,3.8238);
\coordinate (F) at (1.806,3.9003);
\coordinate (G) at (2.4412,3.5143);
\coordinate (H) at (2.6084,3.1);
\coordinate (I) at (2.6327,2.4881);
\coordinate (J) at (2.6689,1.7548);
\coordinate (K) at (2.4279,1.1534);

\draw[use Hobby shortcut, thick, fill=black!25, postaction=show curve controls]
%\draw[use Hobby shortcut, thick, fill=black!25]
([out angle=157]A).. controls (1.4,0.57)..(B)..controls (1.05,1)..(C)..controls(0.7623,2.9231)..(D)..controls(0.9135,3.652)..(E)..controls(1.4995,3.94)..(F)..controls(2.2047,3.797)..(G)..controls(2.546,3.3372)..(H)..controls(2.6,2.8578)..(I)..controls(2.6931,1.9799)..(J)..controls(2.6347,1.5298)..(K)..controls(2.1187,0.7201)..([in angle=40]A);

  \foreach \i in {A,B,C,D,E,F,G,H,I,J,K}
  {
   \draw [fill, red] (\i) circle (2.5pt);
   \node[left] at (\i) {\i};
  }


\end{scope}

\end{tikzpicture}

\end{document}

The code above also shows the control points. You can comment those to get the original image.enter image description here

1
  • Can you try to perceive the result as intersecting pathes instead?
    – MS-SPO
    Feb 7, 2023 at 9:24

2 Answers 2

4
\documentclass[tikz, border=1cm]{standalone}
\usetikzlibrary{hobby}
\begin{document}
\begin{tikzpicture}[very thick, use Hobby shortcut]
\begin{scope}
\clip[closed] (1,0) .. (-0.5,2) .. (2,4) .. (3.5,3) .. (2.5,2);
\filldraw[fill=gray, closed] (1,-0.5) .. (0.5,3) .. (1,3.8) .. (2.3,3) .. (1.8,1);
\end{scope}
\draw[closed] (1,0) .. (-0.5,2) .. (2,4) .. (3.5,3) .. (2.5,2);
\end{tikzpicture}
\end{document}

Curved shape with filled area

You can also use blank from the Hobby package like e.g. here: https://tex.stackexchange.com/a/656517/8650

1
  • The solution turned to be so simple and thus elegant. By the way, I was getting errors because of the clip command until I put the arguments after \begin{tikzpicture}, which I don't understand.
    – aaragon
    Feb 7, 2023 at 15:36
3

It's easy if you draw your curves with the syntax

... (O) to[out=90,in=220] (P) ...

and then repeat the common paths.

For example, a simplified drawing (with lees points),

\documentclass[tikz,border=2mm]{standalone}

\begin{document}
\begin{tikzpicture}[line cap=round]
%\draw[green] (0,-3) grid[step=0.5] (5,3);
\coordinate (O) at (0,0);
\coordinate (P) at (1.2,2.1);
\coordinate (Q) at (2.1,2.5);
\coordinate (R) at (4.7,1.3);
\coordinate (S) at (3.7,0);
\coordinate (T) at (3.3,-1.5);
\coordinate (U) at (0.6,-2.1);
\draw[line width=2pt] (O) to[out=90,in=220] (P) to[out=40,in=195] (Q)
     to[out=15,in=90] (R) to[out=270,in=60] (S) to[out=240,in=80] (T)
     to[out=260,in=310,looseness=1.2] (U) to[out=130,in=270] (O);
\draw[blue,fill=gray] (P) to[out=40,in=195] (Q) to[out=-40,in=90,looseness=1.4] (T)
     to[out=260,in=310,looseness=1.2] (U) to[out=100,in=250,looseness=0.8] (P);
%\foreach \i in {P,Q,T,U}
%  \fill[red] (\i) circle (1.5pt) node[left] {$\i$};
\end{tikzpicture}
\end{document}

will produce:

enter image description here

You must log in to answer this question.

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