6

In the process of typing up a set of lecture notes for a course, I found myself in need of a nice picture of a torus knot, which basically comes down to drawing a very complicated line. With some trickery, I was able to produce the simplest such knot, which is not even really a knot (but it's a start...). The code is as follows:

\documentclass{article}
\usepackage{tikz}
\begin{document} 


\begin{tikzpicture}[scale=2]
\draw (-3.5,0) .. controls (-3.5,1.2) and (-1.5,1.5) .. (0,1.5);
\draw[xscale=-1] (-3.5,0) .. controls (-3.5,1.2) and (-1.5,1.5) .. (0,1.5);
\draw[rotate=180] (-3.5,0) .. controls (-3.5,1.2) and (-1.5,1.5) .. (0,1.5);
\draw[yscale=-1] (-3.5,0) .. controls (-3.5,1.2) and (-1.5,1.5) .. (0,1.5);

\draw (-2,.2) .. controls (-1.5,-0.05) and (-1,-0.15) .. 
    (0,-.15) .. controls (1,-0.15) and (1.5,-0.05) .. (2,0.2);
\draw (-1.7,0.1) .. controls (-1.5,0.15) and (-1,0.25) .. 
    (0,.25) .. controls (1,0.25) and (1.5,0.15) .. (1.7,0.1);
\begin{scope}[rotate=10]
    \draw[draw=none] (0,-1.32) arc (270:630:3.06cm and 1.32cm)
    coordinate[pos=0.375] (a) coordinate[pos=0.875] (b);
    \draw[red] (0,-1.32) arc (270:405:3.06cm and 1.32cm);
    \draw[red,densely dashed] (a) arc (45:225:3.06cm and 1.32cm);
    \draw[red] (b) arc (225:270:3.06cm and 1.32cm);
\end{scope}
\end{tikzpicture}

\end{document}

and the output is:

enter image description here

However, I'm also interested in being able to produce a picture of nontrivial knots such as a loop that wraps around one way three times while "going around the hole" once, and my method does not generalize. My question, therefore, is: Is it possible to efficiently produce pictures such as these (one may also think of natural generalizations like lines on surfaces of arbitrary genus), using TikZ? I should add that I already have a way of efficiently producing a picture of any (compact) orientable surface (without boundary, up to homotopy equivalence---I'm typing notes for an algebraic topology class): It's just the lines on them that I don't know how to quickly draw.

This is a related, yet much simpler question (not a duplicate).

Danu
  • 968
  • 1
    Maybe you could post the code for efficiently producing arbitrary orientatable surfaces? Generally, TikZ is not going to be the most efficient solution for 3D unless it is pretty simple, I don't think, because everything has to be faked i.e. it doesn't really think in 3D but only really knows about 2D. At least, that's how I understand it. – cfr Jan 19 '16 at 12:59
  • @cfr The code for arbitrary orientable surfaces is just a slight modification from the torus: It replaces the right hand side of the torus by a segment that, when mirrored, can be "sewn" to the right hand side of a torus or, again, to itself. In principle I'm also open to usage of other packages, but I'd prefer a TikZ solution. – Danu Jan 19 '16 at 13:21
  • 2
    (@cfr, and) In case there are math-haters, "arbitrary orientable surfaces" are well-classified and what Danu commented are all possibilities, up to homotopy equivalent. See this wiki section. That is to say, if one can draw what Danu commented, they can draw "all arbitrary orientable surfaces". Sounds exciting, right? – Symbol 1 Jan 19 '16 at 14:54
  • @Symbol1 Yup, that's what I was talking about. I'll add the conditions compact & without boundary, I guess, to avoid confusion. – Danu Jan 19 '16 at 15:01
  • @Symbol1 For the record, I'm by no means a 'math-hater', but it has been a while and I did only a little topology even at the time. But, still, TikZ is not the best tool for 3D stuff in general because you can't manipulate objects as 3D objects. At least, that's what I've understood. Whereas in other software, you can treat them as 3D objects. – cfr Jan 19 '16 at 15:45
  • @AlanMunn Thanks, but I think that what I'm looking for is not exactly a knot diagram. – Danu Jan 19 '16 at 22:35
  • 1
    Related: http://tex.stackexchange.com/questions/70090/3d-helix-torus-with-hidden-lines/149759#149759 – Chris Chudzicki Jan 20 '16 at 12:55
  • Incidentally, for compact, oriented surfaces with boundary, there's always the tqft package. – Andrew Stacey Feb 17 '16 at 20:47

1 Answers1

7

This approach checks if the normal vector is pointing to your eyes -- if so, it draws solid lines.

Edit

Please compile this by XeLaTeX! Or one can replace greek letters in csnames by "safe" latin letters.

\documentclass[border=9,tikz]{standalone}
    \usepackage{tikz-3dplot}
    \usetikzlibrary{decorations}

\begin{document}

\foreach\j in{10,20,...,360}{
    \tdplotsetmaincoords{30}{\j}
    \def\R{5}
    \def\r{2}
    \def\N{2}
    \def\n{3}
        \pgfmathsetmacro\S{30*\N*\n}
        \pgfmathsetmacro\X{sin(-\tdplotmaintheta)*sin(-\tdplotmainphi)}
        \pgfmathsetmacro\Y{sin(-\tdplotmaintheta)*cos(-\tdplotmainphi)}
        \pgfmathsetmacro\Z{cos(-\tdplotmaintheta)}

    \tikz[tdplot_main_coords]{
        \path(-10cm,-10cm)(10cm,10cm);
        \draw[dashed](\R+\r,0,0)foreach\i in{0,...,\S}{
            \pgfextra{
                \pgfmathsetmacro\t{360*\N*(\i/\S)}
                \pgfmathsetmacro    \τ{\n/\N*\t}   \pgfmathsetmacro   \ι{\N*\t}
                \pgfmathsetmacro\rsinτ{\r*sin(\τ)} \pgfmathsetmacro\sinι{sin(\ι)}
                \pgfmathsetmacro\rcosτ{\r*cos(\τ)} \pgfmathsetmacro\cosι{cos(\ι)}
            }
            --({(\rcosτ+\R)*\cosι},{(\rcosτ+\R)*\sinι},\rsinτ)
        };
        \draw(\R+\r,0,0)foreach\i in{0,...,\S}{
            \pgfextra{
                \pgfmathsetmacro\t{360*\N*(\i/\S)}
                \pgfmathsetmacro    \τ{\n/\N*\t}   \pgfmathsetmacro   \ι{\N*\t}
                \pgfmathsetmacro\rsinτ{\r*sin(\τ)} \pgfmathsetmacro\sinι{sin(\ι)}
                \pgfmathsetmacro\rcosτ{\r*cos(\τ)} \pgfmathsetmacro\cosι{cos(\ι)}
                \pgfmathparse{
                    \rcosτ*\cosι*\X + \rcosτ*\sinι*\Y + \rsinτ*\Z
                }
                \ifdim\pgfmathresult pt<0pt
                    \def\to{--}
                \else
                    \def\to{}
                \fi
            }
            \to({(\rcosτ+\R)*\cosι},{(\rcosτ+\R)*\sinι},\rsinτ)
        };
    }
}
\end{document}

ascii version:

\documentclass[border=9,tikz]{standalone}
    \usepackage{tikz-3dplot}
    \usetikzlibrary{decorations}

\begin{document}

\foreach\j in{10,20,...,360}{
    \tdplotsetmaincoords{30}{\j}
    \def\R{5}
    \def\r{2}
    \def\N{2}
    \def\n{3}
        \pgfmathsetmacro\S{30*\N*\n}
        \pgfmathsetmacro\X{sin(-\tdplotmaintheta)*sin(-\tdplotmainphi)}
        \pgfmathsetmacro\Y{sin(-\tdplotmaintheta)*cos(-\tdplotmainphi)}
        \pgfmathsetmacro\Z{cos(-\tdplotmaintheta)}

    \tikz[tdplot_main_coords]{
        \path(-10cm,-10cm)(10cm,10cm);
        \draw[dashed](\R+\r,0,0)foreach\i in{0,...,\S}{
            \pgfextra{
                \pgfmathsetmacro\t{360*\N*(\i/\S)}
                \pgfmathsetmacro    \TAU{\n/\N*\t}   \pgfmathsetmacro   \IOTA{\N*\t}
                \pgfmathsetmacro\rsinTAU{\r*sin(\TAU)} \pgfmathsetmacro\sinIOTA{sin(\IOTA)}
                \pgfmathsetmacro\rcosTAU{\r*cos(\TAU)} \pgfmathsetmacro\cosIOTA{cos(\IOTA)}
            }
            --({(\rcosTAU+\R)*\cosIOTA},{(\rcosTAU+\R)*\sinIOTA},\rsinTAU)
        };
        \draw(\R+\r,0,0)foreach\i in{0,...,\S}{
            \pgfextra{
                \pgfmathsetmacro\t{360*\N*(\i/\S)}
                \pgfmathsetmacro    \TAU{\n/\N*\t}   \pgfmathsetmacro   \IOTA{\N*\t}
                \pgfmathsetmacro\rsinTAU{\r*sin(\TAU)} \pgfmathsetmacro\sinIOTA{sin(\IOTA)}
                \pgfmathsetmacro\rcosTAU{\r*cos(\TAU)} \pgfmathsetmacro\cosIOTA{cos(\IOTA)}
                \pgfmathparse{
                    \rcosTAU*\cosIOTA*\X + \rcosTAU*\sinIOTA*\Y + \rsinTAU*\Z
                }
                \ifdim\pgfmathresult pt<0pt
                    \def\to{--}
                \else
                    \def\to{}
                \fi
            }
            \to({(\rcosTAU+\R)*\cosIOTA},{(\rcosTAU+\R)*\sinIOTA},\rsinTAU)
        };
    }
}

\end{document}
David Carlisle
  • 757,742
Symbol 1
  • 36,855