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
draw (x,0) -- (1,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:

Enter image description here

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

\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);
  • 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.
    – SebGlav
    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.
    – Zaragosa
    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.
    – SebGlav
    May 11 at 18:48

3 Answers 3


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.
    \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};

  • Thank you very much, this is much more than what I was looking for. Thank you!
    – Zaragosa
    May 11 at 18:59
  • I was too slow. I think I like your solution better anyway. (+1)
    – Sandy G
    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:

enter image description here

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

enter image description here



    \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;




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

Try this code:


        \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$};  


enter image description here

  • 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.
    – Zaragosa
    May 11 at 18:06

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.