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.

I am trying to generate a path from a list of directions (as seen on the numpad). The coordinates are generated correctly, but because I use multiple call to \path the arrowheads are drawn on each segment. How do I change this code to only draw the starting arrowhead on the first segment and the ending arrowhead on the last segment? I have unsuccessfully tried to have one \path outside the \foreach and only coordinates inside.

edit: It should work for any arrow shape passed in the optional argument.

enter image description here

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand{\directedPath}[5][]
{
  \edef\start{#2}
  \edef\stop{#3}
  \edef\step{#4}
  \edef\directions{#5}
  \coordinate (c0) at (\start);
  \foreach [var=\dir, count=\cur] in \directions
  {
    % current coordinate dx
    \pgfmathparse{(1-(1-1/sqrt(2))*mod(\dir, 2))*\step*(mod(\dir-1, 3)-1)}
    \edef\dx{\pgfmathresult}
    % current coordinate dy
    \pgfmathparse{(1-(1-1/sqrt(2))*mod(\dir, 2))*\step*(div(\dir-1, 3)-1)}
    \edef\dy{\pgfmathresult}
    % previous coordinate index
    \pgfmathparse{int(\cur - 1)}
    \xdef\prev{\pgfmathresult}
    % current coordinate
    \coordinate (c\cur) at ($(c\prev) + (\dx, \dy)$);
    % draw partial path
    \ifnum \cur>1
      \path [#1] (c\prev) -- (c\cur);
    \fi
  }
  \path [#1] (\start) -- (c1);
  \path [#1] (c\cur) -- (\stop);
}

\begin{document}

\begin{tikzpicture}
  \node [draw=green] (Start) at (0, 0) {Start};
  \node [draw=red] (End) at (5, 2) {End};
  \directedPath[draw=black, >->]{Start}{End}{1.0}{3,6,9,8,7,8,9,6,3}
\end{tikzpicture}

\end{document}
share|improve this question
    
Quick fix would be removing >-> and using \path [#1,>-] (\start) -- (c1); \path [#1,->] (c\cur) -- (\stop); –  percusse Jul 14 '13 at 19:00
    
While this solves the problem as stated, it is not what I intended. I should have been more specific. I want it to accept the arrow type as part of the optional argument, making it work for any type of arrowhead. –  Linus Jul 14 '13 at 19:23
1  
How about making the entire path a single \path command? Would that be an acceptable solution? –  Loop Space Jul 14 '13 at 19:27
    
You can provide the start and end arrow types as separate keys. –  percusse Jul 14 '13 at 19:46
    
@AndrewStacey Absolutely. That would probably be the best solution. –  Linus Jul 14 '13 at 19:59

2 Answers 2

up vote 4 down vote accepted

There is no question that this need to be done in one single path but you can do this quite easily with the turtle library.

Simply define a direction (and a factor) for every digit.

As the direction key only turns the “turtle”, also include the forward key which includes a to[/tikz/turtle/how] path to the relative coordinate in direction and the given distance, i.e.

to[/tikz/turtle/how] ++ (<direction>:<distance>)

The Start and End simply insert a move to to (Start) and a (final?) line to to (End) (or whatever the how style is currently).

Of course, you can use the math from your question in the setup of the digit styles, but this is just faster (for TikZ and to write up).

I opted for a grid-like output which needs the factor sqrt(2) for the diagonal directions. Set this factor to 1 to get the same distance as in your question. (I also changed the example a little bit to get a symmetrical result.)

I have created and used an auxiliary style for the setup, marked by an @. It may also preferable to simply define this style in a /aux path as we won’t use it again or really need it in the /tikz path.

This also makes it easy to set all factors to 1 by omitting the value of the forward key (the default is /tikz/turtle/distance anyway if no value is given), i.e.

@setup turtle digits/.style n args={3}{
  /tikz/turtle/#1/.style={
    /tikz/turtle/direction=#2,
    /tikz/turtle/forward}}

(There is no real reason to set the value of the forward key to a fixed distance as it would be more consistent to change the distance value.)

If you suddenly feel that the keys shouldn’t be called 1, 2, … 9 but 1 step, 2 step, … 9 step you simply add  step after #1.

Code

\documentclass[tikz,convert]{standalone}
\usetikzlibrary{turtle}
\tikzset{
  @setup turtle digits/.style n args={3}{
    /tikz/turtle/#1/.style={
      /tikz/turtle/direction=#2,
      /tikz/turtle/forward={#3*\pgfkeysvalueof{/tikz/turtle/distance}}}},
  @setup turtle digits={1}{south west}{1.41421},
  @setup turtle digits={2}{south}     {1},
  @setup turtle digits={3}{south east}{1.41421},
  @setup turtle digits={4}{left}      {1},
  @setup turtle digits={6}{right}     {1},
  @setup turtle digits={7}{north west}{1.41421},
  @setup turtle digits={8}{north}     {1},
  @setup turtle digits={9}{north east}{1.41421},
  turtle/.cd,
    Start/.style={/tikz/insert path={(#1)}},
    End/.style={/tikz/insert path={to[/tikz/turtle/how] (#1)}},
    Start/.default=Start,
    End/.default=End,
}
\begin{document}
\begin{tikzpicture}
  \node [draw=green] (Start) at (0, 1) {Start};
  \node [draw=red]   (End)   at (5, 2) {End};
  \draw [draw=black, >->] [turtle={Start, 2, 3, 6, 9, 8, 7, 8, 9, 6, 3, End}];
\end{tikzpicture}
\end{document}

Output

with the factors

enter image description here

without the factors

enter image description here

share|improve this answer
    
I actually like the grid-like path more, even though it doesn't behave exactly like in my example. I assume you have the source for that as well, could you possibly provide it? –  Linus Jul 15 '13 at 11:02
    
@Linus I have updated my answer including the code for the grid-like approach. It is pretty much the same except for the factor. It shouldn’t be hard to customize this for different problems. –  Qrrbrbirlbel Jul 15 '13 at 17:07
    
@Qrrbrirlbel Trying to understand how this example works. What exactly does "@setup" do? –  Linus Jul 18 '13 at 22:30
    
@Linus I have updated my answer. @setup turtle digits is simply an auxiliary style that makes it possible to define the styles 1 through 9 consistently. You can check out two other answers of mine that uses the turtle library [1] or at least the basic principle behind it [2]. –  Qrrbrbirlbel Jul 19 '13 at 4:00
    
Thief, thief! Qrrbrbirlbel! We hates it, we hates it forever!! (That's for stealing my green tick.) –  Loop Space Jul 19 '13 at 11:54

Here's a single path version:

\documentclass{article}
%\url{http://tex.stackexchange.com/q/123997/86}
\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand{\directedPath}[5][]
{
  \coordinate (c0) at (#2);
  \path (c0)
  \foreach [var=\dir,count=\cur] in {#5}
  {
    ++({(1-(1-1/sqrt(2))*mod(\dir, 2))*#4*(mod(\dir-1, 3)-1)},{(1-(1-1/sqrt(2))*mod(\dir, 2))*#4*(div(\dir-1, 3)-1)}) coordinate (c\cur)
  };
  \path[#1] (#2) -- (c1) \foreach [var=\dir,count=\cur] in {#5}
  {
    -- (c\cur)
  } -- (#3);
}


\begin{document}

\begin{tikzpicture}
  \node [draw=green] (Start) at (0, 0) {Start};
  \node [draw=red] (End) at (5, 2) {End};
  \directedPath[draw=black, >->]{Start}{End}{1.0}{3,6,9,8,7,8,9,6,3}
\end{tikzpicture}


\end{document}

The two foreach loops are because the path starts and ends at non-zero sized nodes, but the displacements are relative to the node centres. In the second path, there's an extra (c1) which is needed due to the issue raised at Draw a path between many nodes using foreach. For an alternative solution, see the answers there.

Single path with foreach

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.