2

The below figure explains all. How can I achieve a red dashed line in an efficient way?

enter image description here

The ugly code below is what I got so far.

\documentclass{article}
\usepackage{tikz}
\begin{document}
    \begin{tikzpicture}
        \draw (-3, -3) grid (5, 5);
        \draw[dashed, color=red] (0+0.1, 0-0.1) -- (1+0.1, 0-0.1) -- (1+0.1, 2-0.1)-- (2+0.1, 2-0.1) -- (2+0.1, 4-0.1) -- (3-0.1, 4-0.1) -- (3-0.1, 1+0.1) -- (2-0.1, 1+0.1) -- (2-0.1, -1+0.1) -- (0+0.1, -1+0.1) -- (0+0.1, 0-0.1);
    \end{tikzpicture}   
\end{document}
Stefan Pinnow
  • 29,535

1 Answers1

3

Welcome to TeX.SE! Yes, you can simplify things in the sense that you need only to specify far less coordinates. Your contour will boil down to

\path[Outline={distance 0.45cm and style {draw=red,dashed}}] 
            (0.05,-0.5) -- ++(1.45,0) -- ++(0,2)
            --++ (1,0) -- ++(0,2.45);

The price you pay is that you need to make some preparations.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations}
% based on https://tex.stackexchange.com/a/103088/121799
% and https://tex.stackexchange.com/a/423581/121799
\def\pgfdecoratedcontourdistance{0pt}

\pgfkeys{/pgf/decoration/contour distance/.code={%
    \pgfmathparse{#1}%
    \let\pgfdecoratedcontourdistance=\pgfmathresult},%
    /pgf/decoration/contour name/.store in=\ContourName,
    /pgf/decoration/contour name=mycontour
}

\pgfdeclaredecoration{contour lineto}{start}
{
    \state{start}[next state=draw, width=0pt]{
    \pgfcoordinate{\ContourName-0}{\pgfpoint{0pt}{\pgfdecoratedcontourdistance}}
        \pgfpathlineto{\pgfpoint{0pt}{\pgfdecoratedcontourdistance}}%
    }
    \state{draw}[next state=draw, width=\pgfdecoratedinputsegmentlength]{       
        \pgfmathparse{-\pgfdecoratedcontourdistance*cot(-\pgfdecoratedangletonextinputsegment/2+90)}%
        \let\shorten=\pgfmathresult%
        \pgfpathlineto{\pgfpoint{\pgfdecoratedinputsegmentlength+\shorten}{\pgfdecoratedcontourdistance}}%  
    %\stepcounter{Outline}
    \pgfcoordinate{\ContourName-1}{\pgfpoint{\pgfdecoratedinputsegmentlength+\shorten}{\pgfdecoratedcontourdistance}}
    }
    \state{final}{
        \pgfpathlineto{\pgfpoint{\pgfdecoratedinputsegmentlength}{\pgfdecoratedcontourdistance}}%
        \pgfpathlineto{\pgfpoint{\pgfdecoratedinputsegmentlength}{0pt}}
    }   
}
\tikzset{Outline/.style args={distance #1 and style #2}{ postaction={
        decoration={contour lineto, contour distance=-#1,contour name=mycontourA},
        #2,decorate},
        postaction={
        decoration={contour lineto, contour distance=#1,contour name=mycontourB},
        #2,decorate},}}

\begin{document}
    \begin{tikzpicture}
        \draw (-3, -3) grid (5, 5);
        \path[Outline={distance 0.45cm and style {draw=red,dashed}}] 
        (0.05,-0.5) -- ++(1.45,0) -- ++(0,2)
        --++ (1,0) -- ++(0,2.45);
    \end{tikzpicture}   
\end{document}

enter image description here

  • Thanks a lot! Your code perfectly works for the example above, but what if an area surrounded by a red line has, say 2x2 block? It looks like your code only works if the area can be described by a certain path. I think this should be asked separately, so I will post another question. – Juyoung Jeong Aug 09 '18 at 19:21
  • @JuyoungJeong Yes, there are limitations. (Of course a 2x2 block can be drawn with a simple rectangle.) It depends on what you want. If you want the contour vary its thickness, this might also be doable. A perhaps simpler solution can be obtained by drawing all the stuff on the background layer and then patch these things together. None of this is elegant, but after all you also increase the number of parameters. –  Aug 09 '18 at 19:28
  • Related (more general question) can be found here https://tex.stackexchange.com/questions/445375/tikz-drawing-a-line-inside-of-certain-shape2 – Juyoung Jeong Aug 09 '18 at 19:45