Неожиданное поведение украшений стрел на узлах: появляются множественные стрелы и пробелы

Неожиданное поведение украшений стрел на узлах: появляются множественные стрелы и пробелы

Я использую knotstikzlibrary для рисования узлов и хочу сориентировать узлы, т. е. добавить стрелку. Я использую стиль оформления, который я назвал "arrowat", который вставляет стрелку в нужное место (например, \draw[arrowat=0.5]даст стрелку на полпути вдоль полученной линии). Он определяется следующим образом

\tikzset{% 
    arrowat/.style={%
        postaction={decorate,decoration={
                markings,
                mark=at position #1 with {\arrow[xshift=2pt]{>}}}}
    }
}

Однако, когда я пытаюсь использовать этот стиль на узле, возникают некоторые проблемы: в некоторых местах все работает просто отлично, но если я пытаюсь нарисовать стрелку в некоторых других местах, появляются несколько стрелок (и пробелы в линии). Ниже приведен MWE, показывающий как случай, когда все работает просто отлично (слева), так и случай, когда нет (справа). Мой вопрос: как мне это исправить или, скорее, предотвратить?

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

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.markings,knots}

\tikzset{% 
    arrowat/.style={%
        postaction={decorate,decoration={
                markings,
                mark=at position #1 with {\arrow[xshift=2pt]{>}}}}
    }
}
\begin{document}

\begin{tikzpicture}
    \begin{knot} [consider self intersections, ignore endpoint intersections=false, clip width=7, flip crossing=3]
    \strand [thick, arrowat=0.8] (0,0)
    to [out=180, in=270] (-1,1)
    to [out=90, in=180] (1,2.5)
    to [out=0, in=90] (3,1)
    to [out=270, in=0] (2,0)
    to [out=180, in=270] (-0.2,2.5)
    to [out=90, in=180] (1,3.8)
    to [out=0, in=90] (2.2,2.5)
    to [out=270, in=0] (0,0);
\end{knot}
\end{tikzpicture}

\begin{tikzpicture}
    \begin{knot} [consider self intersections, ignore endpoint intersections=false, clip width=7, flip crossing=3]
    \strand [thick, arrowat=0.5] (0,0)
    to [out=180, in=270] (-1,1)
    to [out=90, in=180] (1,2.5)
    to [out=0, in=90] (3,1)
    to [out=270, in=0] (2,0)
    to [out=180, in=270] (-0.2,2.5)
    to [out=90, in=180] (1,3.8)
    to [out=0, in=90] (2.2,2.5)
    to [out=270, in=0] (0,0);
    \end{knot}
\end{tikzpicture}

\end{document}

решение1

У меня нет истинного (т.е. элегантного) решения. Просто любопытно отчасти понять, что происходит, и проверить, как часто TiкЗдумаетон находится в позиции 0.5. В этом примере это 10 раз, вы можете проверить это, раскомментировав \typeout{\number\value{arrowcount}}. Затем можно добавить переключатель, который указывает, в каком из них стрелка действительно должна быть нарисована. Соответствующий стиль называется conditional arrow at.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.markings,knots}
\newcounter{arrowcount}
\tikzset{% 
    arrowat/.style={%
        postaction={decorate,decoration={
                markings,
                mark=at position #1 with {\arrow[xshift=2pt]{>}}}}
    },
    conditional arrow at/.style 2 args={%
        postaction={decorate,decoration={
                markings,
                mark=at position #1 with {\stepcounter{arrowcount}%
                %\typeout{\number\value{arrowcount}}%
                \ifnum\value{arrowcount}=#2
                \arrow[xshift=2pt]{>}%
                \fi}}}
    },
}
\begin{document}

\begin{tikzpicture}
    \begin{knot} [consider self intersections, ignore endpoint intersections=false, clip width=7, flip crossing=3]
    \strand [thick, arrowat=0.8] (0,0)
    to [out=180, in=270] (-1,1)
    to [out=90, in=180] (1,2.5)
    to [out=0, in=90] (3,1)
    to [out=270, in=0] (2,0)
    to [out=180, in=270] (-0.2,2.5)
    to [out=90, in=180] (1,3.8)
    to [out=0, in=90] (2.2,2.5)
    to [out=270, in=0] (0,0);
\end{knot}
\end{tikzpicture}

\begin{tikzpicture}
    \begin{knot} [consider self intersections, ignore endpoint intersections=false, clip width=7, flip crossing=3]
    \strand [thick,conditional arrow at={0.5}{6}] (0,0)
    to [out=180, in=270] (-1,1)
    to [out=90, in=180] (1,2.5)
    to [out=0, in=90] (3,1)
    to [out=270, in=0] (2,0)
    to [out=180, in=270] (-0.2,2.5)
    to [out=90, in=180] (1,3.8)
    to [out=0, in=90] (2.2,2.5)
    to [out=270, in=0] (0,0);
   \end{knot}
\end{tikzpicture}

\end{document}

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

При использовании ключа ситуация улучшается в 2 раза (как и ожидалось) only when rendering. Тогда у вас есть «всего» 5 слотов, и каждый из них действительно ведет к стрелке.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.markings,knots}
\newcounter{arrowcount}
\tikzset{% 
    arrowat/.style={%
        postaction={decorate,decoration={
                markings,
                mark=at position #1 with {\arrow[xshift=2pt]{>}}}}
    },
    conditional arrow at/.style 2 args={%
        postaction={decorate,decoration={
                markings,
                mark=at position #1 with {\stepcounter{arrowcount}%
                \typeout{\number\value{arrowcount}}%
                \ifnum\value{arrowcount}=#2
                \arrow[xshift=2pt]{>}%
                \fi}}}
    },
}
\begin{document}

\begin{tikzpicture}
    \begin{knot} [consider self intersections, ignore endpoint intersections=false, clip width=7, flip crossing=3]
    \strand [thick, arrowat=0.8] (0,0)
    to [out=180, in=270] (-1,1)
    to [out=90, in=180] (1,2.5)
    to [out=0, in=90] (3,1)
    to [out=270, in=0] (2,0)
    to [out=180, in=270] (-0.2,2.5)
    to [out=90, in=180] (1,3.8)
    to [out=0, in=90] (2.2,2.5)
    to [out=270, in=0] (0,0);
\end{knot}
\end{tikzpicture}

\begin{tikzpicture}
    \begin{knot} [consider self intersections, ignore endpoint intersections=false, clip width=7, flip crossing=3]
    \strand [thick,only when rendering/.style={conditional arrow at={0.5}{3}}] (0,0)
    to [out=180, in=270] (-1,1)
    to [out=90, in=180] (1,2.5)
    to [out=0, in=90] (3,1)
    to [out=270, in=0] (2,0)
    to [out=180, in=270] (-0.2,2.5)
    to [out=90, in=180] (1,3.8)
    to [out=0, in=90] (2.2,2.5)
    to [out=270, in=0] (0,0);
   \end{knot}
\end{tikzpicture}

\end{document}

Так что, похоже, проблема в том, что путь разбивается на сегменты. Это говорит нам, что вместо этого мы можем прикрепить стрелку к невидимому пути.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.markings,knots}
\newcounter{arrowcount}
\tikzset{% 
    arrowat/.style={%
        postaction={decorate,decoration={
                markings,
                mark=at position #1 with {\arrow[xshift=2pt,opacity=1]{>}}}}
    },
}
\begin{document}

\begin{tikzpicture}
    \begin{knot} [consider self intersections, ignore endpoint intersections=false, clip width=7, flip crossing=3]
    \strand [thick, arrowat=0.8] (0,0)
    to [out=180, in=270] (-1,1)
    to [out=90, in=180] (1,2.5)
    to [out=0, in=90] (3,1)
    to [out=270, in=0] (2,0)
    to [out=180, in=270] (-0.2,2.5)
    to [out=90, in=180] (1,3.8)
    to [out=0, in=90] (2.2,2.5)
    to [out=270, in=0] (0,0);
\end{knot}
\end{tikzpicture}

\begin{tikzpicture}
    \begin{knot} [consider self intersections, ignore endpoint intersections=false, clip width=7, flip crossing=3]
    \def\mypath{(0,0) to [out=180, in=270] (-1,1)
    to [out=90, in=180] (1,2.5)
    to [out=0, in=90] (3,1)
    to [out=270, in=0] (2,0)
    to [out=180, in=270] (-0.2,2.5)
    to [out=90, in=180] (1,3.8)
    to [out=0, in=90] (2.2,2.5)
    to [out=270, in=0] (0,0)}
    \draw[thick,opacity=0,arrowat=0.55] \mypath;
    \strand [thick] \mypath;
   \end{knot}
\end{tikzpicture}

\end{document}

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

Это, возможно, самое элегантное из этих предложений, а также показывает, что «истинная» стрелка на отметке 0,5 скрыта перекрестком.

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