
Я пытаюсь сгенерировать путь из списка направлений (как показано на цифровой клавиатуре). Координаты генерируются правильно, но поскольку я использую множественный вызов \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
стиль в данный момент).End
move 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. Для альтернативного решения смотрите ответы там.