1

I am trying to draw a knot using the knots package, but the crossing labels are straight up, which looks bad at most crossings. This is my code:

\begin{tikzpicture}
\begin{knot}[draft mode=crossings, clip width=10pt,consider self intersections,end tolerance=1pt]
\strand[ultra thick]
(0,0.3) to[out=180,in=90]
(-1.2,-1.5) to[out=-90,in=180]
(1,-3.5) to[out=0,in=0,looseness=2]
(0,-1) to[out=180,in=180,looseness=2]
(-1,-3.5) to[out=0,in=-90]
(1.2,-1.5) to[out=90,in=0] (0,0.3);
\end{knot}
\end{tikzpicture}

Bad Trefoil!

How can I change the pins on an individual basis?

Thanks in advance!

3
  • Hmm, the author of the package doesn't seem to have thought of this possibility. It is possible to change all the labels' styles, but the way that the labels are rendered means that the index of a label is forgotten by the time it is laid out -- I tried a simple solution with extra styles indexed by the label number but it didn't work -- so changing an individual label style is a little more complicated. Jul 13, 2018 at 20:18
  • So is the best option probably removing the automatic labels and placing manual ones?
    – user166643
    Jul 13, 2018 at 20:21
  • No, the best option is persuading the author to fix the code ... but in the meantime, I have a fix for you. Jul 13, 2018 at 20:30

1 Answer 1

2

The author of the knots package didn't put a lot of thought in to these labels - they were intended originally only for helping lay out the knot and figure out which crossings to flip. I'm guessing that you want to use them in the final document.

So the best solution would be to modify the existing library to allow for a customisable per-label style. Something like modifying the definition of \knot_render: so that the part that currently reads:

\bool_if:NTF \l__knot_draft_bool
    {
      \tl_set:Nn \l__knot_node_tl {
        \exp_not:N \node[coordinate,
          pin={[knot~ diagram/draft/crossing~ label]
            {\int_use:N \l__knot_intersections_int}}]
      }
    }

was changed to something like:

\bool_if:NTF \l__knot_draft_bool
    {
      \tl_set:Nn \l__knot_node_tl {
        \exp_not:N \node[coordinate,
          pin={[knot~ diagram/draft/crossing~ label, knot~ diagram/draft/crossing~ \int_use:N \l__knot_intersections_int \c_space_tl label/.try]
            {\int_use:N \l__knot_intersections_int}}]
      }
    }

Then you could define styles like draft/crossing 1 label and they'd get executed on the right label.

Without modifying the original package, the alternative is to try to patch the crossing~ label style to execute an additional style which depends on the crossing number. The difficulty with that is that by the time crossing~ label gets executed, the counter \l__knot_intersections_int is no longer useable. So we have to insert a new counter (which adds an extra wriggle as it turns out that the labels are laid out in reverse! Really, the person who wrote this package made some funny decisions.)

Anyway, here's some code that works. Use at your own risk!

\documentclass{article}
%\url{https://tex.stackexchange.com/q/440528/86}
\usepackage{tikz}
\usetikzlibrary{knots}

\ExplSyntaxOn

\int_new:N \l__knot_current_intersection_int

\tikzset{
  knot~ diagram/draft/crossing~ label/.append~ style={
    knot~ diagram/draft/do~ next~ label
  },
  knot~ diagram/draft/do~ next~ label/.code={
    \pgfkeysalso{knot~ diagram/draft/crossing~ \int_eval:n {\l__knot_intersections_int -  \l__knot_current_intersection_int}~ label/.try}
    \int_gincr:N \l__knot_current_intersection_int
  },
  knot~ diagram/reset~ label~ counter/.code={
    \int_gzero:N \l__knot_current_intersection_int
  }
}

\ExplSyntaxOff

\begin{document}

\begin{tikzpicture}
\begin{knot}[
  reset label counter,
  draft mode=crossings,
  clip width=10pt,
  consider self intersections,
  end tolerance=1pt,
  draft/crossing 3 label/.style={
    text=red,
    pin position=45,
  },
  draft/crossing 1 label/.style={
    text=green,
    pin position=135,
  }
]
\strand[ultra thick]
(0,0.3) to[out=180,in=90]
(-1.2,-1.5) to[out=-90,in=180]
(1,-3.5) to[out=0,in=0,looseness=2]
(0,-1) to[out=180,in=180,looseness=2]
(-1,-3.5) to[out=0,in=-90]
(1.2,-1.5) to[out=90,in=0] (0,0.3);
\end{knot}
\end{tikzpicture}

\end{document}

This produces:

labelled trefoil

As a postscript, I've registered this as an issue on the spath3 issue tracker at https://github.com/loopspace/spath3/issues/1

6
  • Is some package needed for \ExplSyntaxOn, it is showing up as an unrecognized command?
    – user166643
    Jul 13, 2018 at 20:53
  • Hmm, you need the expl3 package but the spath3 tikz library should load it so you shouldn't need to load it additionally. But you could try \usepackage{expl3} in the preamble. Jul 13, 2018 at 21:02
  • Still no, I am running LaTeX2e is that the wrong version, the documentation of \ExplSyntaxOn seems to be in the LaTeX3 Documentation...
    – user166643
    Jul 13, 2018 at 21:16
  • No, LaTeX3 is a set of packages built on top of LaTeX2e so you run pdflatex as usual on the above document. Did you try with exactly the document I posted above? You must have the \usetikzlibrary{knots} before the \ExplSyntaxOn stuff. Jul 13, 2018 at 21:53
  • Yes I have copied your code verbatim into TeXstudio. And I am getting this output... NewTrefoil
    – user166643
    Jul 13, 2018 at 22:04

You must log in to answer this question.