# Draw the flat torus

I want to graph a curve on the flat torus, but not on the entire R^2 plane, but on the square [0,1]x[0,1].

For this, I have created a "do...while" with only the initial data of the rational slope. This is:

let m=p/q
let fx(u)=m(1-u) and fy(u)=(1-u)/m
x=0
DO
y=fx(x)
draw (x,0) -- (1,y);
x=fy(y)
draw (0,y) -- (x,1);
WHILE (x=1)


I apologize for the big mistakes in my code. I just wrote my idea since I don't know how to do it in LaTeX, using TikZ for example. How can I do it?

I already did it manually, but it is not the most optimal. Trying to put m=3/4 is supposed to output the following:

I don't want to code where I have to plot everything manually like the following:

\documentclass[border=1mm]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\draw[red] (0,0) -- (1,3/4);
\draw[red] (0,3/4) -- (1/3,1);
\draw[red] (1/3,0) -- (1,1/2);
\draw[red] (0,1/2) -- (2/3,1);
\draw[red] (2/3,0) -- (1,1/4);
\draw[red] (0,1/4) -- (1,1);
\draw (0,0) -- (1,0) -- (1,1) -- (0,1) -- (0,0) -- (1,0);
\end{tikzpicture}
\end{document}

• If you want to restrain your drawing to the (0,0) to (1,1) square, all you have to do is add \clip (0,0) rectangle (1,1) before the drawing. If you don't want to affect all the drawing, put this in a scope. May 11 at 17:30
• I had that idea too but I would still have to graph the lines manually and constrain them to square, which is not a nice thing when I have a slope of 10/11 for example. For this reason I proposed a more programmable idea, the problem is that I don't know how to program (things like for, do while, etc) in latex. May 11 at 17:34
• First, there's no while loop in TikZ, as far as I know. You would have to compute first how many loops you'll have (or stop when you're back to the starting point) and use a foreach loop. Then, applying your alg doesn't seem that hard if you only want the lines. As for the grid now, it could be a bit more tricky because you need it to adjust automatically. Intersting question, indeed, worth the time spent on it. May 11 at 18:48

Here's an option. I defined a command \flattorus with three arguments:

1. (optional) The side of the square in the TikZ picture, in cm. I put 4 as the default value, but of course you can easily change that.
2. The number of columns to split the square into.
3. The number of rows to split the square into.
\documentclass{article}
\usepackage{tikz}
\newcounter{mx}
\newcounter{my}
\newlength{\squareside}
\newcommand*{\flattorus}[3][4]{%
\setcounter{mx}{#2}
\setcounter{my}{#3}
\setlength{\squareside}{#1 cm}

\begin{tikzpicture}[x=\dimexpr\squareside/#2, y=\dimexpr\squareside/#3]
\draw[thick] (0,0) rectangle (#2,#3);
\foreach \x in {0, ..., \value{mx}}
\foreach \y in {0, ..., \value{my}}{
\draw (\x,\y) -- ++(0,1);
\draw (\x,\y) -- ++(1,0);
\draw[red, thick] (\x,\y) -- ++(1,1);
};
\node[below left] at (0,0) {0};
\node[below] at (#2,0) {1};
\node[left] at (0,#3) {1};
\foreach \x in {1, ..., \value{mx}}
\node[below] at (\x,0) {\x/#2};
\foreach \y in {1, ..., \value{my}}
\node[left] at (0,\y) {\y/#3};
\end{tikzpicture}
}
\begin{document}
\flattorus{3}{4}
\flattorus{5}{2}
\flattorus[2]{2}{3}
\end{document}


• Thank you very much, this is much more than what I was looking for. Thank you! May 11 at 18:59
• I was too slow. I think I like your solution better anyway. (+1) May 11 at 20:08

A nice solution was posted by @Vincent (+1) but this was already in the works so I figured I'd post it as an alternative.

Here is a macro \flattorus that takes two arguments (and one additional optional argument) to draw the flat torus. \flattorus[<scale factor>]{y}{x} draws the line of slope y/x on the torus. Default scale is 2 which produces a square of side length 2cm.

For example, \flattorus{3}{4}\qquad\flattorus{5}{3} produces:

And \flattorus[6]{10}{11} produces

\documentclass{article}

\usepackage{tikz}

\newcommand{\flattorus}[3][2]{\begin{tikzpicture}[scale=#1]
\foreach \k[evaluate=\k as \j using int(\k-1)] in {2,...,#2}{
\draw[gray!30] ({(\j)/#2},0)node[black, below]{$\frac{\j}{#2}$}--++(0,1);}
\foreach \k[evaluate=\k as \j using int(\k-1), evaluate=\k as \p using #2*#3] in {2,...,#3}{\xdef\xy{\p}
\draw[gray!30] (0,{(\j)/#3})node[black, left]{$^{\j}\!/\!_{#3}$}--++(1,0);}
\foreach \k[evaluate=\k as \j using int(\k-1), evaluate=\k as \x using frac(\k*#3/\xy), evaluate=\k as \y using frac(\k*#2/\xy)] in {1,...,\xy}{
\draw[red, thick]({frac(\j*#3/\xy)},{frac(\j*#2/\xy)})--({\x+less(\x,1/\xy)},{\y+less(\y,1/\xy)});}
\draw (0,0)node[below left]{0}--(1,0)node[below]{1}--(1,1)--(0,1)node[left]{1}--cycle;
\end{tikzpicture}}

\begin{document}

\flattorus[6]{10}{11}

\end{document}

• Muchas gracias por tu aporte, me gustó tu solución!!! May 11 at 20:15
• @Sandy G Does your code print out the correct graph for negative slope? Jun 21 at 5:33

Try this code:

\documentclass[10pt,a4paper]{article}

\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[scale=10]
\draw[gray!30,xstep=.3333,ystep=.25] (0,0) grid (1,1);

\draw[red,line width=2pt] (0,0) -- (1,3/4);
\draw[red,line width=2pt] (0,3/4) -- (1/3,1);
\draw[red,line width=2pt] (1/3,0) -- (1,1/2);
\draw[red,line width=2pt] (0,1/2) -- (2/3,1);
\draw[red,line width=2pt] (2/3,0) -- (1,1/4);
\draw[red,line width=2pt] (0,1/4) -- (1,1);
\foreach \x in {0,1/3,2/3,1}
\draw (\x,.02)--(\x,-.02) node[below] {\bfseries $\x$};
\foreach \y in {0,1/4,1/2,3/4,1}
\draw (.02,\y)--(-.02,\y) node[left] {\bfseries $\y$};
\end{tikzpicture}
\end{document}


Output:

• Thank you so much for the help, but I think my question was misunderstood. My question is how would I do a code in which I only have to put the value of m. For example, when I put m=3/4, what you sent me would come out, but what happens if I want m=10/11? How would the graph come out? My problem is precisely not having to make each graph but having something programmable. May 11 at 18:06