TikZ: Объединение нескольких путей внутри и вне foreach

TikZ: Объединение нескольких путей внутри и вне foreach

Я пытаюсь сгенерировать путь из списка направлений (как показано на цифровой клавиатуре). Координаты генерируются правильно, но поскольку я использую множественный вызов \path, наконечники стрелок рисуются на каждом сегменте. Как мне изменить этот код, чтобы рисовать только начальный наконечник стрелок на первом сегменте и конечный наконечник стрелок на последнем сегменте? Я безуспешно пытался иметь один \path вне \foreach и только координаты внутри.

правка: должно работать для любой формы стрелки, переданной в необязательном аргументе.

введите описание изображения здесь

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

решение1

Нет сомнений, что это нужно сделать одним путем, но вы можете сделать это довольно легко с помощью библиотеки turtle.

Просто определите направление (и множитель) для каждой цифры.

Так как directionключ только поворачивает «черепаху», также включите ключ forward, который включает to[/tikz/turtle/how]путь к относительной координате в directionи заданный distance, т.е.

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

И просто вставьте to и (final?) to (или какой там Startстиль в данный момент).Endmove to(Start)line to(End)how

Конечно, вы можете использовать математику из вашего вопроса при настройке стилей цифр, но это просто быстрее (для TikZ и написания).

Я выбрал вывод в виде сетки, которому нужен фактор sqrt(2)для диагональных направлений. Установите этот фактор на , 1чтобы получить то же расстояние, что и в вашем вопросе. (Я также немного изменил пример, чтобы получить симметричный результат.)

Я создал и использовал вспомогательный стиль для настройки, отмеченный @. Также может быть предпочтительнее просто определить этот стиль в /auxпути, поскольку мы не будем использовать его снова или он действительно не понадобится в /tikzпути.

Это также позволяет легко задать все факторы, 1опустив значение ключа forward(по умолчанию /tikz/turtle/distanceв любом случае, если значение не указано), т.е.

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

(Нет никаких реальных причин устанавливать значение ключа forwardна фиксированном расстоянии, поскольку было бы более последовательно изменять distanceзначение.)

Если вы вдруг чувствуете, что клавиши не должны называться 1, 2, …, 9а 1 step, 2 step, …, 9 stepвы просто добавляете  stepпосле #1.

Код

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

Выход

с факторами

введите описание изображения здесь

без факторов

введите описание изображения здесь

решение2

Вот версия с одним путем:

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

Два цикла foreach нужны, потому что путь начинается и заканчивается в узлах ненулевого размера, но смещения относятся к центрам узлов. Во втором пути есть дополнительный, (c1)который необходим из-за проблемы, поднятой вНарисуйте путь между многими узлами с помощью foreach. Для альтернативного решения смотрите ответы там.

Один путь с foreach

Связанный контент