8

First, I'd like to apologize if this question has already been asked before. I am trying to produce an image of a fundamental domain of the action of the modular group (that is, $PSL_2(\mathbb{Z})$) acting on the Poincaré hyperbolic plane using TikZ, and I was wondering if there is an easy way to go about doing that. In particular, I would like to recreate the image on pg. 33 of this text: http://www.math.ou.edu/~kmartin/mfs/ch3.pdf, or see this image from Wikipedia:

from Wikipedia

Any help is appreciated.

  • Do you know the equations that determine the "curvy" parts of the figure? – Herr K. May 11 '13 at 6:21
  • I've inserted the picture from Wikipedia since it's easier. This is different from the one in your text, but note that yours is pretty much a randomly chosen fundamental domain (also, note that there is no such thing as the fundamental domain). – Ryan Reich May 11 '13 at 6:56
  • yes, that was a typo, sorry. the one in the text is a fundamental domain for $\Gamma_0(2)$, and i'm not sure how to get the curves to work out appropriately. – Max May 11 '13 at 7:10
  • 1
    So the curves are half circles. Where are their centres and what radii do they have? Besides the circles, you have some simple lines with tick marks and a shaded are bordered by three axe parallel lines and a part of a circle. So, the only question is the centres and radii of the circles. – Toscho May 11 '13 at 7:44
10

I have no idea how the radius in each iteration is computed or how you determine the x-steps, but in principle you can do something like this:

Code

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{arrows}

\begin{document}

\pgfmathsetmacro{\myxlow}{-2}
\pgfmathsetmacro{\myxhigh}{2}
\pgfmathsetmacro{\myiterations}{6}

\begin{tikzpicture}[scale=2]
    \draw[-latex](\myxlow-0.1,0) -- (\myxhigh+0.2,0);
    \pgfmathsetmacro{\succofmyxlow}{\myxlow+0.5}
    \foreach \x in {\myxlow,\succofmyxlow,...,\myxhigh}
    {   \draw (\x,0) -- (\x,-0.05) node[below,font=\tiny] {\x};
    }
    \foreach \y  in {0.2,0.4,...,1}
    {   \draw (0,\y) -- (-0.05,\y) node[left,font=\tiny] {\pgfmathprintnumber{\y}};
    }
    \draw[-latex](0,-0.1) -- (0,1.2);
    \clip (\myxlow,0) rectangle (\myxhigh,1.1);
    \foreach \i in {1,...,\myiterations}
    {   \pgfmathsetmacro{\mysecondelement}{\myxlow+1/pow(2,floor(\i/3))}
        \pgfmathsetmacro{\myradius}{pow(1/3,\i-1}
        \foreach \x in {-2,\mysecondelement,...,2}
        {   \draw[very thin, blue] (\x,0) arc(0:180:\myradius);
            \draw[very thin, blue] (\x,0) arc(180:0:\myradius);
        }   
    }
\end{tikzpicture}

\end{document}

Output

enter image description here


Edit 1: For filling a region afterwards, I put the clip in a scope to keep the effects local. If you use clip multiple times, the intersection of all is used, so I did it as the folllowing: First I clip a rectangular region from -0.5 to 0.5, then I clip the "outside" of the middle arc, which results in the region you seek. Hint: you can replace the clips by \fill[opacity=0.5] for a visualisation how the clipping region is constructed.

Output, without layers

enter image description here

As you can see, the disadvantage of filling afterwards is that it paints over the existing lines. This can be remedied by using layers. You first draw everything in the main layer, then you fill in the background layer:

Code

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{arrows}

\pgfdeclarelayer{background}
\pgfsetlayers{background,main}

\begin{document}

\pgfmathsetmacro{\myxlow}{-2}
\pgfmathsetmacro{\myxhigh}{2}
\pgfmathsetmacro{\myiterations}{6}

\begin{tikzpicture}[scale=2]
    \draw[-latex](\myxlow-0.1,0) -- (\myxhigh+0.2,0);
    \pgfmathsetmacro{\succofmyxlow}{\myxlow+0.5}
    \foreach \x in {\myxlow,\succofmyxlow,...,\myxhigh}
    {   \draw (\x,0) -- (\x,-0.05) node[below,font=\tiny] {\x};
    }
    \foreach \y  in {0.2,0.4,...,1.4}
    {   \draw (0,\y) -- (-0.05,\y) node[left,font=\tiny] {\pgfmathprintnumber{\y}};
    }
    \draw[-latex](0,-0.1) -- (0,1.6);
    \begin{scope}   
        \clip (\myxlow,0) rectangle (\myxhigh,1.1);
        \foreach \i in {1,...,\myiterations}
        {   \pgfmathsetmacro{\mysecondelement}{\myxlow+1/pow(2,floor(\i/3))}
            \pgfmathsetmacro{\myradius}{pow(1/3,\i-1}
            \foreach \x in {-2,\mysecondelement,...,2}
            {   \draw[very thin, blue] (\x,0) arc(0:180:\myradius);
                \draw[very thin, blue] (\x,0) arc(180:0:\myradius);
            }   
        }
    \end{scope}
    \begin{scope}
        \begin{pgfonlayer}{background}
            \clip (-0.5,0) rectangle (0.5,1.7);
            \clip   (1,1.7) -| (-1,0) arc (180:0:1) -- cycle;
            \fill[gray,opacity=0.8] (-1,-1) rectangle (1,2);
        \end{pgfonlayer}
    \end{scope}
\end{tikzpicture}

\end{document}

Outout, with layers

enter image description here

  • that's awesome dude, thanks so much. i think it is relatively clear that i am a tikz novice, so i apologize if this is a stupid question, but how would one go about shading in a particular region of the figure? that is, say i wanted to color one of the areas bordered by blue lines with a dark gray color -- is there a simple way to do so? – Max May 11 '13 at 17:22
  • I think clipping multiple times would be best. I'll get back to you shortly. – Tom Bombadil May 11 '13 at 18:09

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.