# Draw a $\epsilon$ neighborhood

I would like how to draw a $\epsilon$ neighborhood of a set with smooth boundary in "tikz".

                \documentclass[tikz, border=5mm]{standalone}
\usepackage{tikz}
\usepackage{amsmath}
\begin{document}

\begin{tikzpicture}[>=latex]
\draw plot [smooth cycle, tension=0.6] coordinates {(4.4,0.4) (5,0.2) (5.8,0.6) (6.5773,0.5421)(6.4905,1.1074)  (5.9752,1.2828) (5.4,1.4) (4.6,1) };
\end{tikzpicture}
\end{document}


The first thing to realise is that this is impossible. PDF, and therefore TikZ, can only draw cubic bézier lines and enlargening a cubic bézier by the same distance all around can produce something that is not a cubic bézier any more.

So any solution is going to be something of a hack.

Having said that, here's a solution that does produce a path that is a set distance from the original curve. It exploits the fact that when a line is drawn then its thickness obeys exactly the constraint that you are trying to force: that the line is drawn so that at any point on the curve, the width of the line as measured orthogonal to the curve is the given thickness. So if only there were a way to draw only the outer edge of a thick line when drawing the curve ...

That's what this does. To get the edge, we draw the line twice with the second time being white and a little thinner than the first time (as you want it dashed, I decided not to use the double as that can lead to artifacts when viewing the document). To get only the outer edge, we clip against the original curve.

The odd dashing effect is because the dashes are the correct width along the original curve but then scale proportionally through the thickness of the line (taking out the white over-draw shows what's going on there).

\documentclass[tikz, border=5mm]{standalone}
%\url{http://tex.stackexchange.com/q/335826/86}
\usepackage{tikz}
\usepackage{amsmath}
\begin{document}

\begin{tikzpicture}[>=latex]
\begin{scope}[even odd rule]
\clip (3,-1) rectangle (8,3) plot [smooth cycle, tension=0.6] coordinates {(4.4,0.4) (5,0.2) (5.8,0.6) (6.5773,0.5421)(6.4905,1.1074)  (5.9752,1.2828) (5.4,1.4) (4.6,1) };
\draw[line width=1cm,dashed] plot [smooth cycle, tension=0.6] coordinates {(4.4,0.4) (5,0.2) (5.8,0.6) (6.5773,0.5421)(6.4905,1.1074)  (5.9752,1.2828) (5.4,1.4) (4.6,1) };
\draw[line width=.9cm,white] plot [smooth cycle, tension=0.6] coordinates {(4.4,0.4) (5,0.2) (5.8,0.6) (6.5773,0.5421)(6.4905,1.1074)  (5.9752,1.2828) (5.4,1.4) (4.6,1) };
\end{scope}
\draw[line width=.5mm] plot [smooth cycle, tension=0.6] coordinates {(4.4,0.4) (5,0.2) (5.8,0.6) (6.5773,0.5421)(6.4905,1.1074)  (5.9752,1.2828) (5.4,1.4) (4.6,1) };
\end{tikzpicture}
\end{document}


Just remember:

If there's something strange,
Who're you gonna call?
TeX-busters!

• Ahaha! Brilliant! – mattdanzi Oct 25 '16 at 19:16
• Cases to test this one: sharp corners, shapes with narrow regions (smaller than epsilon), shapes with something behind it. Note that the outline thickness code basically does the work of generating pseudo-beziers and removing cusps; doing it manually is going to be really annoying in a real(tm) programming language, let alone TeX. – Yakk Oct 25 '16 at 19:29
• @Yakk Exactly. A solution to the full problem is going to be quite tricky to do as there are many edge cases as you describe. I'm hoping that the OP doesn't need a full solution and that there's enough here to work with. – Loop Space Oct 25 '16 at 20:13

If the boundary of the set is parameterized counterclockwise as (x(t),y(t)) then the boundary of its epsilon-neighborhood is parametrized as: Now suppose we are given only a finite set of, say, N points on the curve (x(t), y(t)), so t assumes integer values modulo N. Then we can approximate the derivative x'(t) by (x(t+1)-x(t-1))/2, and analogously for y'(t).

Putting this into practice:

\documentclass[tikz, border=5mm]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
%\draw[help lines,line width=.6pt,step=1] (4,0) grid (7,2);
%\draw[help lines,line width=.3pt,step=.1] (4,0) grid (7,2);
\draw plot [smooth cycle, tension=0.6] coordinates
{(4.4,0.4)(4.6,0.25)(5,0.2)(5.4,0.4)(5.8,0.6)(6.3,0.55)(6.55,0.55)
(6.6,0.8)(6.5,1.1)(6.35,1.2)(6,1.3)(5.8,1.35)(5.4,1.4)(5,1.25)
(4.6,1)(4.45,0.8)};
\draw[dashed] plot [smooth cycle, tension=0.6] coordinates
{(4.3,0.37)(4.56,0.14)(5.03,0.06)(5.47,0.26)(5.83,0.44)(6.29,0.42)
(6.59,0.5)(6.7,0.81)(6.57,1.14)(6.39,1.29)(6.03,1.4)(5.82,1.46)
(5.38,1.54)(4.93,1.39)(4.52,1.1)(4.34,0.84)};
\end{tikzpicture}
\end{document}


Here I used twice the number the points as originally given. The result is not perfect (especially on the regions of larger curvature), but increasing the number of points should of course improve quality.

I did the calulations using a Google spreadsheet. I'm sure there is a way of telling TikZ to do the calculations, but I was too lazy to find it out. If someone wants to append my answer and automate this part, please feel free to do so.

This is a simple solution with ellipse shape, but maybe you were looking for that specific set shape..

\documentclass[tikz, border=5mm]{standalone}
\usepackage{tikz}
\usepackage{amsmath}
\begin{document}

\begin{tikzpicture}[>=latex]
\draw[dashed] (0,0) ellipse (4cm and 2cm);
\draw (0,0) ellipse (3cm and 1.5cm);
\draw[<->] (0,1.5) -- (0,2) node[right,midway] {$\epsilon$};
\end{tikzpicture}

\end{document}


• I Draw the following set – Victor Hugo Oct 25 '16 at 13:05
• \documentclass[tikz, border=5mm]{standalone} \usepackage{tikz} \usepackage{amsmath} \begin{document} \begin{tikzpicture}[>=latex] \draw plot [smooth,tension=0.8] coordinates {(-1.3697,3.7545) (1.5,4) (3.5,5) (5.5,3) (8,2) (8,-0.5)} ; \end{tikzpicture} \end{document} – Victor Hugo Oct 25 '16 at 13:05
• @VictorHugo Mmm impressive, but I think it has nothing to do with the question or with a possible solution – mattdanzi Oct 25 '16 at 13:10
• I need a curved set, as mentioned in the comment. Is there a command to increase proportionally a drawing? – Victor Hugo Oct 25 '16 at 13:18
• @VictorHugo ok now I understand – mattdanzi Oct 25 '16 at 13:21

This should work.

\documentclass[border=0pt]{standalone}
\usepackage{mathtools,tikz}\usetikzlibrary{decorations.markings,arrows}
\begin{document}\begin{tikzpicture}\tikzset{every node}=[font=\huge]
\tikzstyle{coarselydashed}=[dash pattern=on 7pt off 8pt]
\draw[coarselydashed,line width=1pt,rounded corners=52pt](-1,3)--(2,0)--(6,3)--(10,0)--(13,3)--(12,6)--(6,9)--(1,7)--cycle;
\draw[shade,top color=black!96,bottom color=black!16,fill opacity=0.64,line width=2pt,rounded corners=39pt](0,3)--(2,1)--(6,4)--(10,1)--(12,4)--(10,6.4)--(6,8)--(1,6)--cycle;
\begin{scope}[decoration={markings,mark=at position 1 with {\arrow[scale=1.2]{triangle 45},color=black!96}}]
\draw[line width=1pt,-,postaction={decorate}](6,7.8) to (6,8.5);\node (epsilon) at (6.5,8.1) {$\epsilon$};
\end{scope}
\end{tikzpicture}\end{document}

• It works, but it is clear that we do not have the same distance from the dotted line. I'm looking for a command to do this. – Victor Hugo Oct 25 '16 at 14:38