TikZ: Combinando vários caminhos dentro e fora do foreach

TikZ: Combinando vários caminhos dentro e fora do foreach

Estou tentando gerar um caminho a partir de uma lista de direções (como visto no teclado numérico). As coordenadas são geradas corretamente, mas como eu uso várias chamadas para \path, as pontas das setas são desenhadas em cada segmento. Como altero esse código para desenhar apenas a ponta da seta inicial no primeiro segmento e a ponta da seta final no último segmento? Tentei sem sucesso ter um \path fora do \foreach e apenas coordenadas dentro.

editar: Deve funcionar para qualquer formato de seta passado no argumento opcional.

insira a descrição da imagem aqui

\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}

Responder1

Não há dúvida de que isso precisa ser feito em um único caminho, mas você pode fazer isso facilmente com a turtlebiblioteca.

Basta definir uma direção (e um fator) para cada dígito.

Como a directionchave apenas gira a “tartaruga”, inclua também a forwardchave que inclui um to[/tikz/turtle/how]caminho para a coordenada relativa em directione o dado distance, ou seja

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

O Starte Endsimplesmente insira um move toto (Start)e um (final?) line toto (End)(ou qualquer que seja o howestilo atualmente).

Claro, você pode usar a matemática da sua pergunta na configuração dos estilos de dígitos, mas isso é apenas mais rápido (para TikZ e para escrever).

Optei por uma saída tipo grade que precisa do fator sqrt(2)para as direções diagonais. Defina esse fator como 1para obter a mesma distância da sua pergunta. (Também mudei um pouco o exemplo para obter um resultado simétrico.)

Criei e utilizei um estilo auxiliar para o setup, marcado por uma extensão @. Também pode ser preferível simplesmente definir esse estilo em um /auxcaminho, pois não o usaremos novamente ou realmente precisaremos dele no /tikzcaminho.

Isto também facilita a definição de todos os fatores, 1omitindo o valor da forwardchave (o padrão é /tikz/turtle/distanceassim mesmo se nenhum valor for fornecido), ou seja

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

(Não há nenhuma razão real para definir o valor da forwardchave para uma distância fixa, pois seria mais consistente alterar o distancevalor.)

Se de repente você sentir que as teclas não deveriam ser chamadas 1, 2, … 9mas 1 step, 2 step, … 9 stepbasta adicionar  stepdepois #1.

Código

\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}

Saída

com os fatores

insira a descrição da imagem aqui

sem os fatores

insira a descrição da imagem aqui

Responder2

Aqui está uma versão de caminho único:

\documentclass{article}
%\url{https://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}

Os dois loops foreach ocorrem porque o caminho começa e termina em nós de tamanho diferente de zero, mas os deslocamentos são relativos aos centros dos nós. No segundo caminho, há um extra (c1)que é necessário devido à questão levantada emDesenhe um caminho entre muitos nós usando foreach. Para uma solução alternativa, veja as respostas lá.

Caminho único com foreach

informação relacionada