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 should I draw pathes with multiple branches in Tikz? The draw command only provides 1-dimensional pathes. Is there a way to naturally merge them?

My thoughts: Usually I would simply combine multiple draw commands. But in the case of e.g. dashed lines the drawing fails at the tie points.

Minimal working example:

\documentclass{article}

\usepackage{tikz}

\begin{document}
  \begin{tikzpicture}
    % way 1: only draw missing part
    \draw[dashed,->] (0,0)   -- (1,0) -- (1,1);
    \draw[dashed]    (2.5,0) -- (1,0);
  \end{tikzpicture}
  \vspace{1em} % dummy space

  \begin{tikzpicture}
    % way 2: draw full path
    \draw[dashed,->] (0,0)   -- (1,0) -- (1,1);
    \draw[dashed,->] (2.5,0) -- (1,0) -- (1,1);
  \end{tikzpicture}
\end{document}

The result is looking ugly in both cases:

Result for MWE

share|improve this question
    
densely dashed helps although it does not entirely eliminate the problem. –  cfr Aug 5 at 11:06
    
Do you have a lot of these or just a few? –  percusse Aug 5 at 11:22
    
Just a few, but I expect there to be a standard solution, shouldn't it? In any case, please post your idea even if it only works for few of these situations. Maybe it is a good start for a discussion :-) –  matheburg Aug 5 at 11:26
    
Standard solution does not have an easy implementation because dash patterns are PDF objects so they have to be arranged before issued. The easiest is the use dash phase key to a nonzero value. A little more complicated is to get the path length and use the modulo dash pattern to calculate the phase automatically. The actual answer is to go through all the path length computations up to that point. –  percusse Aug 5 at 11:38

4 Answers 4

Not the standard solution, but one way which solves some simple cases like above is to start the drawing at the overlapping side:

\documentclass{article}

\usepackage{tikz}

\begin{document}
  \begin{tikzpicture}
    % way 3: start drawing at overlapping point
    \draw[dashed,<-] (1,1)   -- (1,0) -- (0,0);
    \draw[dashed,<-] (1,1) -- (1,0) -- (2.5,0);
  \end{tikzpicture}
\end{document}

Result for way 3

However, this question is still not satisfactorily answered for the general case.

share|improve this answer

This is some explanation about my comment under the question;

\documentclass[tikz]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}

    \coordinate (a) at (0,0);
    \coordinate (b) at (10.9pt,0);
    \coordinate (c) at (1,0);

    \draw[densely dashed,->] (a) -| ($(b)+(0,1)$);
    \draw[->]  %
         let \p1=($(a)-(b)$), % the cornering point carried to origin
             \n1={mod(veclen(\x1,\y1),5pt)>3?%length of the cornering path up to
                  3-mod(veclen(\x1,\y1),5pt):% corner modulo dash on pattern
                  mod(veclen(\x1,\y1),5pt))
                  }  
in [densely dashed,dash phase=\n1] (b) -- (c);
\end{tikzpicture}
\end{document}

enter image description here

For the 5pt, I knew what densely dashed pattern was, but you can define all these beforehand. But still I think this is not possible with an easy fix for general paths. One immediate reason is that, the second path doesn't know the first one's existence. So a true path merge is not possible out-of-the-box.

For a quick reference to get dash pattern lengths,

\tikzstyle{ultra thin}=              [line width=0.1pt]
\tikzstyle{very thin}=               [line width=0.2pt]
\tikzstyle{thin}=                    [line width=0.4pt]
\tikzstyle{semithick}=               [line width=0.6pt]
\tikzstyle{thick}=                   [line width=0.8pt]
\tikzstyle{very thick}=              [line width=1.2pt]
\tikzstyle{ultra thick}=             [line width=1.6pt]

\tikzstyle{solid}=                   [dash pattern=]
\tikzstyle{dotted}=                  [dash pattern=on \pgflinewidth off 2pt]
\tikzstyle{densely dotted}=          [dash pattern=on \pgflinewidth off 1pt]
\tikzstyle{loosely dotted}=          [dash pattern=on \pgflinewidth off 4pt]
\tikzstyle{dashed}=                  [dash pattern=on 3pt off 3pt]
\tikzstyle{densely dashed}=          [dash pattern=on 3pt off 2pt]
\tikzstyle{loosely dashed}=          [dash pattern=on 3pt off 6pt]
\tikzstyle{dashdotted}=              [dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt]
\tikzstyle{dash dot}=                [dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt]
\tikzstyle{densely dashdotted}=      [dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt]
\tikzstyle{densely dash dot}=        [dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt]
\tikzstyle{loosely dashdotted}=      [dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt]
\tikzstyle{loosely dash dot}=        [dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt]
\tikzstyle{dashdotdotted}=           [dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt on \the\pgflinewidth off 2pt]
\tikzstyle{densely dashdotdotted}=   [dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt on \the\pgflinewidth off 1pt]
\tikzstyle{loosely dashdotdotted}=   [dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt on \the\pgflinewidth off 4pt]
\tikzstyle{dash dot dot}=         [dash pattern=on 3pt off 2pt on \the\pgflinewidth off 2pt on \the\pgflinewidth off 2pt]
\tikzstyle{densely dash dot dot}=   [dash pattern=on 3pt off 1pt on \the\pgflinewidth off 1pt on \the\pgflinewidth off 1pt]
\tikzstyle{loosely dash dot dot}=   [dash pattern=on 3pt off 4pt on \the\pgflinewidth off 4pt on \the\pgflinewidth off 4pt]
share|improve this answer
    
Thanks a lot for these detailed information. You are right that pathes do not know each others information, but maybe there is/could be created a special command for branched pathes? –  matheburg Aug 5 at 12:51

The simplest way to fix this seems to be to draw three lines all starting from (1,1). This yields:

enter image description here

The tex code:

\documentclass{article}
\usepackage{tikz}

\begin{document}
  \begin{tikzpicture}
    % way 2: draw full path
    \draw[dashed,->] (1,0) -- (1,1);
    \draw[dashed,->] (1,0)--(2.5,0);
    \draw[dashed,->] (1,0)--(0,0);
  \end{tikzpicture}
\end{document}
share|improve this answer
    
Hey Andrew, thank you! However, similar to my answer this only solves the simple cases. What if the pathes split up multiple times, what if we have closed pathes? Additionally this solution provides another strange bahaviour at the tie points with a double-length dash... –  matheburg Aug 5 at 12:48
    
@matheburg I agree with all of your points. Aesthetically, I like the double length dash to support the "weight" of the vertical line, but I don't think I'd like this for lines intersecting horizontally. For dashed lines with a small number of intersections this will, of course, only work if the collinear intersection points are the right distance apart... –  Andrew Aug 5 at 12:55

After thinking about the topic a bit: Every branched path can be interpreted as graph with nodes in branch points/tie points.

Case 1: We have a loop-free graph.

In this case the graph can be interpreted as a tree (simple graph theory). Therefore one can easily follow my first answer starting to plot all pathes at a root node for the tree. All periods of the dashing will be synchronized then.

Example for case 1:

\documentclass{article}
\usepackage{tikz}
\begin{document}
  \begin{tikzpicture}
    % spanning tree starting from some root node (here: (0,0))
    \draw[dashed,->] (0,0) -- (1,1) -- (2,1) -- (4,2);
    \draw[dashed,->] (0,0) -- (1,1) -- (0,2);
    \draw[dashed,->] (0,0) -- (1,1) -- (2,1) -- (3,0) -- (4,0);
  \end{tikzpicture}      
\end{document}

example case 1


Case 2: We have exactly 1 loop in the graph

In this case one has to make sure that the dash phase multiplied by some natural number results in the (euclidean) length of the loop. After doing this we can simply use a spanning tree (plus one edge which closes the loop) to realize a dashed path free of contradictions. Since the phase fits the loop length we wont have a contradiction at adding the "closing edge".

Algorithm in words:

  1. Compute the Euclidean length of your loop L.
  2. Set the edge phase to a number L/N, where N is a natural number (which describes the #edges closing the loop); follow percusse's answer here.
  3. Remove 1 edge from the loop.
  4. Plot the remaining tree (=loop-free graph) with the algorithm from case 1.
  5. Plot another path (starting at the root note from step 4) which closes the loop.

Example for case 2:

\documentclass{article}
\usepackage{tikz}
\begin{document}
  % loop has length 2 + 2*sqrt(2) = 4.8284...
  % N = 20 => (2+2*sqrt(2))/20 = 0.2414
  \begin{tikzpicture}[x=1cm,y=1cm]
    % spanning tree starting from some root node (here: (0,0))
    \tikzstyle{dashed}=[dash pattern=on 0.15cm off 0.0914cm] % 0.15 + 0.0914 = 0.2414
    \draw[dashed] (0,0) -- (1,1) -- (2,1) -- (4,2);
    \draw[dashed] (0,0) -- (1,1) -- (0,2);
    \draw[dashed] (0,0) -- (1,1) -- (2,1) -- (3,0) -- (4,0);
    % closing edge
    \draw[dashed] (0,0) -- (1,1) -- (0,2) -- (0,0);
  \end{tikzpicture}
\end{document}

example case 2

Edit: I have to modify my algorithm and my criteria due to the problem of loops which do not give a possible root node after removing an edge later. I will add information regarding this...


Case 3: We have a graph with multiple loops

In general, this case is impossible to be realized. Simple counter-example: example case 3

In this case we have a loop of length 4 and a loop of length 2+sqrt(2). Having no contradictions at all tie points would imply that there exist natural numbers n and k, s.t. the dash phase can on the one hand be written as 4/n and on the other hand as (2+sqrt(2))/k. This is a contradiction since 4/n is a rational number, but (2+sqrt(2))/k is not.

So everything is lost in a case of multiple loops? Not really. In the (rare) case where you can find a consistent dash phase for all loops you can simply expand the algorithm from case 2. In all other cases I would go on with drawing all edges in independent pathes like Andrew suggested in his post (although this will lead to slightly different dash phases and (acceptable) inconsistancies at the tie points). Another alternative: You could also try to find a good approximation for your purposes.


Future Work:

  • One should provide an all-in-one command for case 1. This cannot be that difficult.
  • Much harder: Providing a command for case 2.
share|improve this answer

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.