6

In TikZ, I want to draw two segments (black) and a dashed trajectory (red) encircling these segments, as shown in the picture. Is there a way to easily draw the dashed trajectory just based on the coordinates of the two segments?

enter image description here

Here is my attempt:

\begin{tikzpicture}
\draw [thick] (1,1) -- (2,2);
\draw [thick] (2,2) -- (2,3.5);
\draw [dashed] (2.2,2) -- (2.2,3.7) -- (1.8,3.7) -- (1.8,2) -- (0.8,1) -- (1.1,0.8) -- (2.2,2);
\end{tikzpicture}

It doesn't look very nice, and I wasn't able to make the curve.

enter image description here

doe
  • 75
  • 1
    Welcome to TEX.SE. please show us what you have tried so far. This is not a just-do-it-for-me site. – Raaja_is_at_topanswers.xyz Jun 10 '19 at 07:23
  • @Raaja Thank you. I have tried searching for this on Google and a number of TikZ tutorials, but could not find how to do this. One approach would be to draw each "dash" separately, but that would be extremely tedious and I can't imagine it's the best approach. Also, I don't think it would work well for the curved part. – doe Jun 10 '19 at 07:33
  • 2
    You can always start something and shows us what you have done. We can take that as a start and then give you (close to) what you want instead of starting from scratch. – Raaja_is_at_topanswers.xyz Jun 10 '19 at 07:46
  • @Raaja I have added my efforts. – doe Jun 10 '19 at 08:18
  • You are welcome and you get my +1. Moreover, from next time, please make it compilable. – Raaja_is_at_topanswers.xyz Jun 10 '19 at 09:04

2 Answers2

7

If you could accept not being dashed, a round cap can help:

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

\begin{document}
\begin{tikzpicture}
\draw [thick] (1,1) -- (2,2);
\draw [thick] (2,2) -- (2,3.5);
\draw [dashed] (2.2,2) -- (2.2,3.7) -- (1.8,3.7) -- (1.8,2) -- (0.8,1) -- (1.1,0.8) -- (2.2,2);

\begin{scope}[xshift=2cm]
\draw[line cap=round, red!30, line width=2.5mm] (1,1)--(2,2)--(2,3.5);
\draw (1,1)--(2,2)--(2,3.5);
\end{scope}

\begin{scope}[xshift=4cm]
\draw[line cap=round, line width=3mm] (1,1)--(2,2)--(2,3.5);
\draw[line cap=round, white, line width=2.5mm] (1,1)--(2,2)--(2,3.5);
\draw (1,1)--(2,2)--(2,3.5);
\end{scope}
\end{tikzpicture}
\end{document}

enter image description here

Update: with some patience and hobby library you could do something like:

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

\begin{document}
\begin{tikzpicture}
\draw (1,1) node (a) {}  --(2,2) node (b) {} --(2,3.5)  node[rotate=45] (c) {};
\draw[dashed, use Hobby shortcut] (a.south west) to[closed, curve through={(a.north west) .. (b.north west) .. (c.north west) .. (c.north east) .. (c.south east) .. (b.south east) .. (a.south east)}] cycle; 
\end{tikzpicture}
\end{document}

enter image description here

Ignasi
  • 136,588
4

The following draws halos around simple paths as the one above. You only need to record the path

\draw[thick,postaction={record path={step=5pt}}] (1,1) -- (2,2) -- (2,3.5);

and then can draw a halo via

\draw[dashed,halo];

enter image description here

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{decorations.markings}
\newcounter{halo}
\tikzset{record path/.style={/utils/exec=\tikzset{halo pars/.cd,#1},
    decorate,decoration={markings,mark=at position 0 with
    {\setcounter{halo}{1}%\typeout{\pgfdecoratedpathlength}
    \path (0pt,{\pgfkeysvalueof{/tikz/halo pars/dist}}) coordinate (halo-L-\number\value{halo})
    (0pt,{-1*\pgfkeysvalueof{/tikz/halo pars/dist}}) coordinate (halo-R-\number\value{halo})
    ({-\pgfkeysvalueof{/tikz/halo pars/dist}/sqrt(2)},{-\pgfkeysvalueof{/tikz/halo pars/dist}/sqrt(2)}) coordinate (halo-A-1)
    ({-\pgfkeysvalueof{/tikz/halo pars/dist}},{0pt}) coordinate (halo-A-2)
    ({-\pgfkeysvalueof{/tikz/halo pars/dist}/sqrt(2)},{\pgfkeysvalueof{/tikz/halo pars/dist}/sqrt(2)}) coordinate (halo-A-3);
     \pgfmathsetmacro{\mystep}{(\pgfdecoratedpathlength-2*\pgfkeysvalueof{/tikz/halo pars/step})/int(1+(\pgfdecoratedpathlength-2*\pgfkeysvalueof{/tikz/halo pars/step})/\pgfkeysvalueof{/tikz/halo pars/step})}
     \xdef\mystep{\mystep}},
    mark=between positions \pgfkeysvalueof{/tikz/halo pars/step} and {\pgfdecoratedpathlength-\pgfkeysvalueof{/tikz/halo pars/step}} step \mystep pt with {\stepcounter{halo}
    \path (0pt,{\pgfkeysvalueof{/tikz/halo pars/dist}}) coordinate (halo-L-\number\value{halo})
    (0pt,{-1*\pgfkeysvalueof{/tikz/halo pars/dist}}) coordinate (halo-R-\number\value{halo});},
    mark=at position 1 with {\stepcounter{halo}
    \path (0pt,{\pgfkeysvalueof{/tikz/halo pars/dist}}) coordinate (halo-L-\number\value{halo})
    (0pt,{-1*\pgfkeysvalueof{/tikz/halo pars/dist}}) coordinate (halo-R-\number\value{halo})
    ({\pgfkeysvalueof{/tikz/halo pars/dist}/sqrt(2)},{\pgfkeysvalueof{/tikz/halo pars/dist}/sqrt(2)}) coordinate (halo-B-1)
    ({\pgfkeysvalueof{/tikz/halo pars/dist}},{0pt}) coordinate (halo-B-2)
    ({\pgfkeysvalueof{/tikz/halo pars/dist}/sqrt(2)},{-\pgfkeysvalueof{/tikz/halo pars/dist}/sqrt(2)}) coordinate (halo-B-3);
    \xdef\LstHaloCoords{(halo-A-1) (halo-A-2) (halo-A-3)}
    \foreach \XX in {1,...,\number\value{halo}}
    {\xdef\LstHaloCoords{\LstHaloCoords\space (halo-L-\XX)}}
    \xdef\LstHaloCoords{\LstHaloCoords\space (halo-B-1) (halo-B-2) (halo-B-3)}
    \foreach \XX in {\number\value{halo},\the\numexpr\number\value{halo}-1,...,1}
    {\xdef\LstHaloCoords{\LstHaloCoords\space (halo-R-\XX)}}
    }}},
    halo/.style={insert path={plot[smooth,samples at={1,...,\number\value{bracep}},variable=\x]
    (bracep-\x)}},halo/.style={insert path={plot[smooth cycle] coordinates {\LstHaloCoords} }},
    halo pars/.cd,dist/.initial=5pt,step/.initial=2pt}
\begin{document}
\begin{tikzpicture}
    \draw[thick,postaction={record path={step=5pt}}] (1,1) -- (2,2) -- (2,3.5);
    \draw[dashed,halo];
\end{tikzpicture}
\end{document}

The halo path is known to TikZ so it can be used for all sorts of things like intersections or fill with pattern (needs the libraries intersections or patterns), e.g.

\draw[thick,postaction={record path={step=5pt}}] (1,1) -- (2,2) -- (2,3.5);
\draw[red,pattern=north west lines,pattern color=blue,halo];

enter image description here

As you can see, the result is not perfect, but can be improved by playing with the step parameter (I chose this on purpose in order not to deceive users). An automatically nice solution that works with much more complicated, in particular self-intersecting, paths is much harder to obtain. However, the above works with curves, too, i.e. not just with straight lines.


Note also that if I only take your dashed contour, add rounded corners and replace the last coordinate by cycle (so that the last corner is also rounded), I get

enter image description here

\documentclass[tikz,border=3.14mm]{standalone}
\begin{document}
\begin{tikzpicture}
\draw [thick] (1,1) -- (2,2);
\draw [thick] (2,2) -- (2,3.5);
\draw [dashed,rounded corners] (2.2,2) -- (2.2,3.7) -- (1.8,3.7) -- (1.8,2) --
(0.8,1) -- (1.1,0.8) -- cycle;
\end{tikzpicture}
\end{document}

Things look arguably even better if one draws the fist line in one stretch and takes into account the slope of the lower leg when drawing the contour.

\documentclass[tikz,border=3.14mm]{standalone}
\begin{document}
\begin{tikzpicture}
\draw [thick] (1,1) -- (2,2) -- (2,3.5);
\draw [dashed,rounded corners] (2.2,1.9) -- (2.2,3.7) -- (1.8,3.7) -- (1.8,2.1) --
(0.8,1) -- (1.1,0.8) -- cycle;
\end{tikzpicture}
\end{document}

enter image description here

If you want the dash pattern to close, use

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{decorations.markings}
\begin{document}
\begin{tikzpicture}
\draw [thick] (1,1) -- (2,2) -- (2,3.5);
\path [rounded corners,preaction={decorate,decoration={markings,mark=at position 0 with {%
\pgfmathsetmacro{\myon}{\pgfdecoratedpathlength/50}
\xdef\myon{\myon}}}},postaction={draw,dash pattern=on \myon pt off \myon pt}] (2.2,1.9) -- (2.2,3.7) -- (1.8,3.7) -- (1.8,2.1) --
(0.8,1) -- (1.1,0.8) -- cycle;
\end{tikzpicture}
\end{document}

enter image description here

  • Wow! The path recording is impressive, but holy cow, that is unreadable. It took me a minute to insert some line-breaks and indentation. Sadly (without dashed) one sees that there are overlaps. I tried way smaller steps, expecting it to be more precise then. But quite the contrary, it leads to more overlaps. Bigger steps lead to smoothing and more 'cutting the edge off'. Nevertheless, being able to use it for lines like these is amazing: \draw[thick,postaction={record path={step=7pt}}] (3,2) arc (50:3:2);. Excellent for my purpose! – BadAtLaTeX Jun 17 '19 at 12:17