I was left with one unresolved issue: on a 2-strand braid,
the parser, which breaks a crossing down into a list of
strands to swap, cannot tell the difference between the
crossing s_1 ("swap 1,2") and the crossing s_2 ("swap 1,2").
Here is an annular braid which has both:
A user who wants to draw a two-strand annular braid like this is probably best off drawing a three-strand braid with an invisible strand (i.e. the strand colour is the page colour and it is the understrand on all its crossings). I was mostly working in matlab/octave, so for myself, I wrote a quick matlab script that can "double up" a strand to convert a two-strand braid into a three-strand braid to achieve this. Here's an example:
Moving away from annular braids, and looking at braids as closures of links, we sometimes find that we have munged a link into a sort of doughnut shape, ready to cut it open and unfurl in a braid (the usual Artin braid). It may from time to time be appropriate, either for clarity or for reasons of space, to draw the braid in this circular form:
To achieve these circular braids, I went back to the braids library. This time, I left Andrew's parsing logic alone, and cut out the drawing logic to replace it with logic to draw arcs and crossings. In this case, rather than add an option to the usual braid pic command, I renamed the library and the pic command, so that I could use regular braids and circular braids as separate libraries in the same tikz picture:
Unlike my annular braids library, I didn't make any effort to make sure all of Andrew's existing options worked. Circular braids do not allow for the specification style a_{1,4}, where non adjacent strands are crossed by building a sequence of crossings; they do not allow for "floors" to be marked, and they do not have all the coordinates that Andrew makes available in a usual braid. The strand style specifications do still work.
The (crossing) width parameter also still works; I replaced crossing height with a parameter I call "innerradius" which specifies how far from the centre of the circle the first (innermost) strand should be. Here are some examples of different radii and crossing widths:
I drew the above manually, using isometric view in Tikz.
A line segment is given by e.g.:
\draw plot[domain=180:360,samples=145] ({cos(\x+45)},{-sin(\x+45)},{2*(\x-180)/180});
With this logic, the order of the \draw commands defines the over-/under-crossing effect. To achieve this programmatically, we need to draw the strands in the right order: the "over" (outer) strands that are currently moving between circle positions 180 and 360 degrees, then the "under" (inner) strands in this part of the circle, then the "under" (inner) strands on the front half of the cylinder, and finally the "over" (outer) strands on the front half of the cylinder.
There are a couple more little fiddles: to draw the "pipe" view version, we set the line style to achieve the 3D effect, and it then works best if the lines are overlapped by a few degrees, to avoid awkward junctions at the line end. To draw the "line" view version, we need to add the "dashed" style on the back of the cylinder. If the number of strands is odd, there may be crossings that happen on the boundary between "front" and "back" of the cylinder (from this perspective), which will require a little extra work to deal with.
In principle, we could take the braids library and chop out the drawing code again, and replace with this logic. However, Andrew's library doesn't draw the strands bit by bit like this. It builds up a path command for each strand, which consists of a sequences of lines/curves and jumps (moves). The strands are then simply drawn one after another.
It's certainly not unthinkable that we could use Andrew's parse logic and then build suitable drawing logic to achieve these cylindrical braids. Anyone?