7

Using the knots package, I have drawn a (3,7)-torus knot. I would like for the inner region of the diagram to be shaded gray.

A minimal working example for the code follows.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{hobby,knots}
\begin{document}

\begin{tikzpicture}[use Hobby shortcut]
\fill[black!30!white] (90:1) \foreach \k in {1,...,7}{--(90+\k*360/7:1)};

\begin{knot}[
  consider self intersections=true,
  ignore endpoint intersections = false,
  flip crossing/.list={1,7,6,11,10, 13, 15, 2}
]
\strand[very thick] ([closed]90:2) foreach \k in {1,...,7} 
   { .. (90-360/7+\k*1080/7:1) .. (90+\k*1080/7:2) } (90:2);
\end{knot}

\end{tikzpicture}
\end{document}

The figure produced by this code follows.

enter image description here

The problem with the figure is that I would like the gray region to fit neatly next to the arcs of the knot diagram that bounds it. There are three issues I would like to fix.

  1. The knot tikzlibrary works by drawing larger white background lines around the strands that appear on top at a crossing. This is how the effect of an over/under crossing is achieved (I think). I want the shaded region to ignore those larger white lines and meet the actual arcs of the knot diagram.
  2. I've guessed the crossing coordinates in my \fill command. Is there anyway to compute exactly what those coordinates are?
  3. The arcs in the inner region are closely approximated by straight line segments. In this case, I could probably get away by filling a path (if question 1 was resolved). However, I do not know how to approach shading some of the regions with curvier boundaries.

Any help is greatly appreciated.

9
  • 1
    Please expand your code snippet into a complete minimal working example: that is, a minimal piece of code that compiles and demonstrates your problem.
    – user30471
    Jan 12 '18 at 22:57
  • @Andrew, I believe I have a minimal working example that shows my problem and my attempt so far. Does this help? Jan 13 '18 at 0:07
  • 1
    Probably related
    – user121799
    Jan 13 '18 at 1:19
  • 1
    If I were you, I'd try to change my mind about what I was trying to draw. How crucial is this? Because it is probably going to be a PITA, to be honest. You can presumably (I guess) get the coordinates from the package - if they are provided in sufficiently accessible form. Then you will need to compensate by an amount equal to the line width less half the distance between doubles. To do this neatly, you'll need to adjust at an angle which depends on the two lines meeting at that coordinate. At least, I think so. Rather you than me, I must say.
    – cfr
    Jan 13 '18 at 2:23
  • 1
    If you wanted all the background grey or something, that'd be easy. Or if you wanted a colour other than white for the borders of the lines. I also wonder if you've thought about what the result will look like. I expect it will look rather odd at the points where the intersections abut the grey. It will look as if the white appears out of the grey, which seems odd. The result won't be properly balanced.
    – cfr
    Jan 13 '18 at 2:25
7

I have no idea how to fill exactly this area, but you can cheat like this :

\documentclass[tikz,border=7pt]{standalone}
\usetikzlibrary{hobby,knots,shapes}

\begin{document}

  \begin{tikzpicture}[use Hobby shortcut]

    \begin{knot}[
        consider self intersections=true,
        ignore endpoint intersections = false,
        flip crossing/.list={1,7,6,11,10, 13, 15, 2}
      ]
      \strand[very thick] ([closed]90:2) foreach \k in {1,...,7}
        { .. (90-360/7+\k*1080/7:1) .. (90+\k*1080/7:2) } (90:2);
    \end{knot}

    \node[regular polygon,regular polygon sides=7,fill,fill opacity=.21, inner sep=6.8mm, rotate=7] {};
  \end{tikzpicture}
\end{document}

enter image description here

2
  • I’m a bit ashamed I did not come up with this solution myself. I suspect cfr is right that the general case is more trouble than it’s worth, but this does get the job done for this example. Jan 13 '18 at 17:31
  • 1
    @AdamLowrance If you put it in a blend scope, you don't have to be as accurate in specifying the path to clip. That might help in cases which are slightly more problematic than this one, even though it still wouldn't help in the general case. (Effectively, you can stop the grey painting over the black, so it doesn't matter if you don't clip perfectly to the white area, except at the intersections.)
    – cfr
    Jan 14 '18 at 3:49
4

Here's a method using blend modes (the PGF manual warns that these might not be supported by all renderers/printers). The thinking behind it is that the white-out part of the knot should blank out other strands of the knot but not anything else. So everything ends up in a blend group and we choose the blend modes appropriately.

To get the actual region, we fill the knot path using the even odd rule and clip against a circle of just the right size (magic numbers courtesy of www.i-just-made-them-up.com). This gets us the correct region (for a more generic shape, one might have to be a bit creative for this part). Drawing the knot over the top sort of works, but has the issue of the white-out showing and hence the use of blend modes.

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

\begin{document}

\begin{tikzpicture}[use Hobby shortcut]

\begin{scope}[blend group=darken]

\begin{scope}[blend group=normal,even odd rule]
\clip (0,0) circle[radius=1.07];
\fill[black!30!white, save Hobby path={knot}] ([closed]90:2) foreach \k in {1,...,7} 
   { .. (90-360/7+\k*1080/7:1) .. (90+\k*1080/7:2) } (90:2);
\end{scope}

\begin{scope}[blend group=normal]
\begin{knot}[
  consider self intersections=true,
  ignore endpoint intersections = false,
  flip crossing/.list={1,7,6,11,10, 13, 15, 2}
]
   \strand[very thick] ([closed]90:2) foreach \k in {1,...,7} { .. (90-360/7+\k*1080/7:1) .. (90+\k*1080/7:2) } (90:2);
\end{knot}
\end{scope}

\end{scope}
\end{tikzpicture}
\end{document}

Result:

shaded knot

Detail of a single junction:

single junction

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.