Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

How can parallel lines elegantly be added to an existing path? I am looking for a solution or hint to, how a general style can be made, that works with any path.

Example path:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
  \draw (0,0) -- (1,1) -| (2,2) -- (3,2) -- (3,1);
\end{tikzpicture}
\end{document}

original path

Same path, with customizable extra lines:

path with extra parallel lines

Here I have drawn two extra lines, just to show, what I mean. Ideally a solution should only add one extra line, but somehow be expandable to any number of lines.

The question: How to build parallel paths between nodes?, where my solution is less than elegant, has inspired me to ask this question.

share|improve this question
    
I'm not sure if the "parallel path" is well defined. Intuitively I can see what you mean, but, what would be its mathematical definition? For example, lets say that the parallel path at distance X is the path such that, at every point, the minimal distance of that point to the original path is X. This sound a reasonable definition, but would produce rounded corners instead of angles... –  JLDiaz Mar 17 '13 at 23:45
    
@JLDiaz: I see your point. Let us say our original path is closed and not self intersecting (a 'loop' of sort). Then you can take each line segment and shift it parallel outward(or inward). Extend(or shorten) the line segments, to make the new path. I am sure that similar ideas can be applied to the general path. –  Hans-Peter E. Kristiansen Mar 17 '13 at 23:55
    
Does the path consist of straight line segments only? –  g.kov Mar 18 '13 at 1:28
    
@g.kov: I must admit, that I do not have an actual application for this ...yet. I am sure that a solution that works for straight line segments will be useful for me and others. –  Hans-Peter E. Kristiansen Mar 18 '13 at 1:42
    
What (I think) is required here, is what vector graphics applications call "outsetting" and "insetting" (usually with closed paths). The shifting/shortening approach is (very) broadly correct, but AFAIK you also need to take into account the angle between consecutive segments. It's ages since I looked at this, but I think a segment should be lengthened by -h*cot(A/2) (A is the angle between segments, h is the outset distance). –  Mark Wibrow Mar 18 '13 at 10:13
add comment

1 Answer

up vote 6 down vote accepted

It turns out some of the work is already done, but an important macro \pgfdecoratedangletonextinputsegment is undocumented (and incorrectly defined - possibly why it is undocumented). Here's a not-very-well tested solution for straight lines only with no mid-path moveto commands. I think dealing with curveto and closepath segments will also prove extra-tricky.

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{decorations}

\def\pgfdecoratedcontourdistance{0pt}

\pgfkeys{/pgf/decoration/contour distance/.code={%
    \pgfmathparse{#1}%
    \let\pgfdecoratedcontourdistance=\pgfmathresult}%
}

\pgfdeclaredecoration{contour lineto}{start}
{
    \state{start}[next state=draw, width=0pt]{
        \pgfpathmoveto{\pgfpoint{0pt}{\pgfdecoratedcontourdistance}}%
    }
    \state{draw}[next state=draw, width=\pgfdecoratedinputsegmentlength]{       
        \pgfmathparse{-\pgfdecoratedcontourdistance*cot(-\pgfdecoratedangletonextinputsegment/2+90)}%
        \let\shorten=\pgfmathresult%
        \pgfpathlineto{\pgfpoint{\pgfdecoratedinputsegmentlength+\shorten}{\pgfdecoratedcontourdistance}}%  
    }
    \state{final}{
        \pgfpathlineto{\pgfpoint{\pgfdecoratedinputsegmentlength}{\pgfdecoratedcontourdistance}}%
    }   
}

\begin{document}

\begin{tikzpicture}

\draw [
    postaction={
        decoration={contour lineto, contour distance=-5pt},
        draw=red, dotted, decorate},
    postaction={
        decoration={contour lineto, contour distance=15pt}, 
        draw=blue, dashed, decorate},
    postaction={
        decoration={contour lineto, contour distance=10pt}, 
        draw=green, decorate}
    ] 
    (0, 0) -- (3, 1) -- (4, 4) -- (6, 4) -- 
    (8,-1) -- (2,-2) -- (5, 2) -- (6, 0);

\end{tikzpicture}


\end{document}

contour example

share|improve this answer
    
This looks like it is exactly, what I imagined. Does your comment about an incorrectly defined macro means, that there is anything wrong with this code? When time permits, I will try to understand the low level part of your code. –  Hans-Peter E. Kristiansen Mar 18 '13 at 16:43
    
Check out closed path, e.g. (0,0)--(6,0)--(3,4.5)--cycle; It might be a good idea to add edge constrains as the lines that intersect the path at the first and the last point. –  g.kov Mar 19 '13 at 6:03
    
@Hans-PeterE.Kristiansen: in the low-level decorations code the macro is (for some reason) defined as B-A instead of A+180-B where A and B are the angle from the horizontal of consecutive segments. The calculation in the cot function given above takes this into account. @k.gov: As it says in the answer "dealing with ... closepath segments will prove extra-tricky". By "extra-tricky", I mean probably impossible to do with out ugly hacking. –  Mark Wibrow Mar 19 '13 at 6:55
    
I’d love your input on this answer which uses almost all of your decoration code. –  Qrrbrbirlbel Sep 16 '13 at 22:03
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.