I was doing some spherical trigonometry and wanted to be able to draw some diagrams like these:

 

 

I was a little unsure about how to proceed. In the past I have made diagrams in in CAD programs as well as in MATLAB; in general I have found they don’t look very professional.
I decided to do some research into some other options to draw spherical geometry. Some alternatives I looked at where using Python (like in this example) another direction I nearly used was the vector drawing program Inkscape. Blender was even suggested, but I  thought this would be overkill.
I then saw some diagrams created with the Tex package TikZ/PGF and thought they where exactly what I wanted. The advsantage of using this package is that there are no actual graphics files. The generated figures are vector based and created during compilation! I think it will take me quite a bit of time to get this working so I will use this page to report on my progress and act as a guide for others.


EDIT: while researching TikZ/PGF I have found there are similar tools like: MetaPost, Asymptote, PSTricks and Sketch.
TikZ/PGF – It Compiles!:
 
I wanted to first start simple and draw some basic shapes and 2D trigonometry. I installed a LaTeX editor on my fresh Mint OS and started out with this very simple .tex file:
p, li { white-space: pre-wra
  1. \documentclass{article}
  2. \usepackage{tikz}
  3. \begin{document}
  4. Test diagram:\\
  5.      \begin{tikzpicture}
  6.      \end{tikzpicture}
  7. \end{document}
  • We want to use the TikZ/PGF package so we have to tell LaTeX to use the package.
  • I usually include some text as a kind of place holder.
  • To start a diagram we invoke/create the the {tikzpicture} environment.

Drawing Some Primitives:

Now, we will start simple and draw two lines to act as our x-y Cartesian axis:

  1. \begin{tikzpicture}
  2.      \draw (-1,0) (1,0);
  3.      \draw (0,-1) (0,1);
  4. \end{tikzpicture}

This produces the following result. Its not overly fancy, but its a start.

  • From this example we have learnt that we can use the \draw command to create a line/path from point (x1, y1) to (x2, y2).
  • “–” is actually a path extension operator which extends a path from one point to another. For example, we could draw a square like this: \draw (-1,-1) (-1,1) (1,1) (1,-1) — (-1,-1);
Now the next basic element/primitive I want to be able to draw is a circle. We can do this in a similar way:

p, li { white-space: pre-wra

  1. \begin{tikzpicture}
  2.      \draw (-1,0) — (1,0);
  3.      \draw (0,-1) — (0,1);
  4.      \draw (-0.5,0.5) circle (0.5);
  5.      \filldraw [gray] (0.5,-0.5) circle (0.5);
  6.      \draw (0.5,0.5) ellipse (0.5 and 0.25); 
  7. \end{tikzpicture}

This produces the following result:

  • Here we can draw a circle at (x,y) and specify a radius.
  • The command to fill is also introduced; instead of \draw, we use \filldraw followed by the colour of the fill.
  • We can also draw an ellipse by specifying two radii.

Adding a Grid:

This is looking a bit better, we have an ill-defined coordinate system and can draw some basic shapes. In order to make the drawing more useful, we might want to add a grid. Instead of drawing lots of squares using the \rectangle command or drawing a multitude of lines, it is simpler/easier to use the grid feature:
  1. \begin{tikzpicture}
  2.      \draw (-1,0) — (1,0);
  3.      \draw (0,-1) — (0,1);
  4.      \draw (0,0) circle (0.8);
  5.      \draw[step=0.1] (0,0) grid (1,1);
  6. \end{tikzpicture}

This produces the following result:

  • Here we have drawn a grid from (x1, y1) to (x2, y2) with a step of 0.1. A unique step can be defined for the x and y directions using xstep and ystep, but we don’t want that in this scenario.
We probaby want the grid to cover the entire diagram. And maybe it would look better being a little sparcer?
  1. \begin{tikzpicture}
  2.      \draw (-1,0) — (1,0);
  3.      \draw (0,-1) — (0,1);
  4.      \draw (0,0) circle (0.8);
  5.      \draw[step=0.2] (-1,-1) grid (1,1);
  6. \end{tikzpicture}

This produces the following result:

Now, whilst the grid looks ok, it appears to have too much presence (is not subdued) in the diagram; we can’t even make out the x and y axis! To fix this we will change the grid colour to gray, reduce the line thickness and move the grid into the background:
  1. \begin{tikzpicture}
  2.      \draw[step=0.2, gray, very thin] (-1,-1) grid (1,1);
  3.      \draw (-1.2,0) — (1.2,0);
  4.      \draw (0,-1.2) — (0,1.2);
  5.      \draw (0,0) circle (0.8);
  6. \end{tikzpicture}

Here is the result:

That’s looking better!

TikZ Styles and introducing Colour:

There is an improvement we can make upon our current diagram… Imagine we have a large document with maybe 100 diagrams all using the same grid, the imagine we want to change the colour of our grid for some reason. We would have to go and edit all 100 diagrams. To make this easier we use styles:
  1. \tikzstyle gridstyle = [style=help lines, color=blue!40]
  2. \begin{document}
  3. Test diagram:\\
  4.      \begin{tikzpicture}
  5.          \draw[step=0.2, style=gridstyle] (-1,-1) grid (1,1);
  6.          \draw (-1.2,0) — (1.2,0);
  7.          \draw (0,-1.2) — (0,1.2);
  8.          \draw (0,0) circle (0.8);
  9.      \end{tikzpicture}
  10. \end{document}
This produces the following result:
  • The first thing we see is how to define a style macro using ‘\tikzstyle gridstyle =’ and how to apply that style to the what we are drawing.
  • We can also see that our style definition is inheriting from the in-built style ‘help lines’. We are then what colour to use; this will overwrite the inherited colour.
  • The ‘!40‘ in the colour: ‘blue!40‘ specifies the alpha or transparency to use.

Arcs and Angles:

Another thing that will be very useful to draw on our diagrams are arcs and angles (and indeed we will need these on our spherical trigonometry diagrams). Have a look at this example:

  1. \begin{tikzpicture}
  2.      \draw[step=0.2, style=gridstyle] (-1,-1) grid (1,1);
  3.      \draw (-1.2,0) — (1.2,0);
  4.      \draw (0,-1.2) — (0,1.2);
  5.      \draw (0,0) circle (0.8);
  6.      \draw (0,1) arc (90:180:1);
  7.      \draw (0.3,0) arc (0:30:0.3);
  8. p, li { white-space: pre-wra
         \draw (0,0) — (0.693,0.4);
  9. \end{tikzpicture}

This produces the following diagram:

 

  • Here we have drawn two arcs. The arc starts from the specified (x,y) coordinate. Following the arc keyword, with then have a triple which is three numbers separated by columns. The first two numbers are angles and the third is the radius of the arc.
  • In the first example we are drawing an arc starting from (0,1) and will be drawing the section that goes from 90deg to 180deg (the top left quadrant of a circle). We are also drawing with a radius of 1.
  • The second arc starts from (0.3,0) and is specified from 0:30deg so it is also drawn clockwise. A smaller radius of 0.3 has been specified.
  • As with a circle, to to draw an elliptical arc two radii should be specified.
  • To calculate the end point of the radius I manually calculated x=r*cosθ, y = r*sinθ.
Filling & Shading, Scaling & Clipping:
While the diagram is now taking shape and close to illustrating some basic trig concepts, we might want to make the diagram a little more fancy by shading in the angle:
  1. \begin{tikzpicture}[scale = 2]
  2.     \clip (-0.1,-0.1) rectangle (1,1);
  3.     \draw[step=0.2, style=gridstyle1] (-1,-1) grid (1,1);
  4.     \draw (-1.2,0) — (1.2,0);
  5.     \draw (0,-1.2) — (0,1.2);
  6.     \draw (0,0) circle (0.8);
  7.     \fill[green!70!black] (0,0) — (3mm,0mm) arc (0:30:3mm) — (0,0);
  8. \end{tikzpicture}

This produces the following diagram:

  • The first thing you might have noticed is that the figure has been scaled/enlarged and clipped/cropped.
  • Scaling is quite straight forward, just include [scale = x] after opening the {tikzpicture} environment.
  • Clipping is quite similar to \draw… but instead of using \draw we use \clip and the following shape/primitive will be used as a mask.
  • We then have the filled/shaded shape. Similar to \clip, we have replaced \draw with \fill and then follow it with the shape to fill; in this case we have defined a closed path.
  • The other new thing is how we have defined the fill colour. We now have ‘green!70!black‘ which means fill with the mixture of 70%green and 30%black. [This expression is possible since pgf uses Uwe Kern’s xcolorpackage]
We don’t have to define a closed path as the path will be automatically closed when using fill. There are some problems however:
p, li { white-space: pre-wra
  1. \begin{tikzpicture}[line width=5]
  2.      \draw (0,0) — (1,0) — (1,1) — (0,0);
  3.      \draw (2,0) — (3,0) — (3,1) — cycle;
  4.      \useasboundingbox (0,1.3); % make bounding box higher
  5. \end{tikzpicture}
  • We can see that the first closed path has not been drawn exactly how we might expect.
  • The second closed path looks better. This is because we used the ‘cycle‘ keyword.
  • Since the line width has been increased so much (to exaggerate the phenomenon) the bounding box needed to be adjusted so the text doesn’t run into the figure.
Now we probably want to lighten the shade of green and include a darker border colour. I do this a lot when using shapes in Word:
  1. \begin{tikzpicture}[scale = 2]
  2.     \clip (-0.1,-0.1) rectangle (1,1);
  3.     \draw[step=0.2, style=gridstyle1] (-1,-1) grid (1,1);
  4.     \draw (-1.2,0) — (1.2,0);
  5.     \draw (0,-1.2) — (0,1.2);
  6.     \draw (0,0) circle (0.8);
  7.     \filldraw[fill=green!20!white, draw=green!50!black]
  8.         (0,0) — (3mm,0mm) arc (0:30:3mm) — cycle;
  9. \end{tikzpicture}
  • Here a fill and draw colour has been defined. Hopefully you agree with me that it looks better.
Specifying Coordinates:
Say we wanted to draw the line representing the sine of the angle; you may recall from one of the diagrams above that I had to manually calculate coordinates on the circle. It turns out tikZ/PGF has a better way:

p, li { white-space: pre-wra

  1. \begin{tikzpicture}[scale = 2]
  2.      \def\R{0.8} % circle radius
  3.      def\ANG{30} % the angle
         \clip (-0.1,-0.1) rectangle (1.2,1.2);
  4.      \draw[step=0.2, style=gridstyle1] (-1,-1) grid (1,1);
  5.      \draw (-1.2,0) — (1.2,0);
  6.      \draw (0,-1.2) — (0,1.2);
  7.      \draw (0,0) circle (\R);
  8.      \filldraw[fill=green!20!white, draw=green!50!black]
  9.           (0,0) — (0.3,0) arc (0:\ANG:0.3) — cycle;
  10.      \draw[red,very thick] (\ANG:\R)+(0,-0.4);
  11. \end{tikzpicture}
  • The first thing I have done to make our figure/diagram easier to manipulate is defined the radius of the circle and the angle we are displaying. This allows us to write more generic expressions and also makes our code/functions more reusable
  • The next thing is how the start point of our line segment is defined. Instead of using (0.693, 0.4) a polar notation has been introduced where we specify an angle and radius: (Angle:Radius).
  • The end of our line segment has also been defined differently. Instead of using absolute coordinates, we have used relative coordinates. This is done by placing a ‘+‘ in front of the coordinate. So in this case it means: from our last point go down 0.4 in y.
The problem here is that we still need to perform a calculation: in this case that 0.8*sin(30). If we change our defined angle or radius that figure will no longer work. It turns out there is another way we can define coordinates:
  1. \begin{tikzpicture}[scale = 2]
  2.      \def\R{0.8} % circle radius
  3.      \def\ANG{40} % the angle
  4.      \clip (-0.1,-0.1) rectangle (1.2,1.2);
  5.      \draw[step=0.2, style=gridstyle1] (-1,-1) grid (1,1);
  6.      \draw (-1.2,0) — (1.2,0);
  7.      \draw (0,-1.2) — (0,1.2);
  8.      \draw (0,0) circle (\R);
  9.      \filldraw[fill=green!20!white, draw=green!50!black]
  10.           (0,0) — (0.3,0) arc (0:\ANG:0.3) — cycle;
  11.      \draw[red,very thick] (\ANG:\R) — (\ANG:\R |- 0,0);
  12.      \draw[blue,very thick] (\ANG:\R) +(0,-0.514) — (0,0);
  13. \end{tikzpicture}
  • The code is now quite flexible instead of specifying the relitive distance to move we have defined the second point in a new way using “|-“. The meaning of (m |- n) is: the intersection of a vertical line through ‘m’ and a horizontal line through ‘n’.
  • The other interesting thing to note is how the blue line segment’s start point is defined. We first define a point using the polar notation and the move relative to that point without drawing i.e we just move the pen. Of course, in this case it would be better to use “(\ANG:\R |- 0,0) — (0,0);” instead.

We now have the lines which represent sine and cosine, but what about the tangent line? It is hard to represent it with the methods employed so far, luckily there is yet another way:

  1. \begin{tikzpicture}[scale = 2]
  2.      \def\R{0.8} % circle radius
  3.      \def\ANG{40} % the angle
  4.      \clip (-0.1,-0.1) rectangle (1.2,1.2);
  5.      \draw[step=0.2, style=gridstyle1] (-1,-1) grid (1,1);
  6.      \draw (-1.2,0) — (1.2,0);
  7.      \draw (0,-1.2) — (0,1.2);
  8.      \draw (0,0) circle (\R);
  9.      \filldraw[fill=green!20!white, draw=green!50!black]
  10.           (0,0) — (0.3,0) arc (0:\ANG:0.3) — cycle;
  11.      \draw[red,very thick] (\ANG:\R) — (\ANG:\R |- 0,0);
  12.      \draw[blue,very thick] (\ANG:\R |- 0,0) — (0,0);
  13.      \draw[very thick,orange] (\R,0) — (intersection of {\R,0–\R,\R} and {0,0–\ANG:\R});
  14. \end{tikzpicture}
  • Here we have found the second point by calculating the intersection of two lines (each of which are defined by two points)
  • I found that the braces where necessary for the correct interpretation.

Ticks and Text:

While the figure is now taking shape our x and y axis are still a little lacking. Lets improve them by adding ticks and arrow heads:

  1. \begin{tikzpicture}[scale = 2]
  2.      \def\R{0.8} % circle radius
  3.      \def\ANG{40} % the angle
  4.      \draw[step=0.2, style=gridstyle1] (-1,-1) grid (1,1);
  5.      \draw [->] (-1.2,0) — (1.2,0); \draw [->] (0,-1.2) — (0,1.2);
  6.      \draw (0,0) circle (\R);
  7.      \filldraw[fill=green!20!white, draw=green!50!black]
  8.           (0,0) — (0.3,0) arc (0:\ANG:0.3) — cycle;
  9.      \foreach \x in {-1,-0.9, …, 1}{
  10.           \draw (\x,-0.05) — (\x,0.05);
  11.      }
  12.      \foreach \y in {-1,-0.9, …,1}{
  13.           \draw (-0.05,\y) — (0.05,\y);
  14.      }
  15. \end{tikzpicture}
  • The arrow heads for the x and y axis prove to be quite easy to add. Just include the [->] option before after the \draw. Arrows heads can also be added to arcs and can have a head on both sides by using [].
  • To add ticks to our axis the for‘ loop is introduced. This allows us to define a symbol (in this case \x), which we iterate over values given in the braces: {}. We could list the values separated by commas but in this case it is easier to specify it by {start, start+step…, end}. The statement(s) in the loop are then repeated for each \x.
  • The y-ticks are produced in a similar way.

Now we might like to add text to our ticks. We can also do that:

  1. \begin{tikzpicture}[scale = 2]
  2.      \clip (-0.4,-0.4) rectangle (1.2,1.2);
  3.      \draw[step=0.2, style=gridstyle1] (-1,-1) grid (1,1);
  4.      \draw [->] (-1.2,0) — (1.2,0); \draw [->] (0,-1.2) — (0,1.2);
  5.      \foreach \i in {-1,-0.5, …, 1}{
  6.           \draw (\i,-0.05) — (\i,0.05);
  7.           \draw (\i, 0) node[anchor=north]{$\i$};
  8.           \draw (-0.05,\i) — (0.05,\i);
  9.           \draw (0, \i) node[anchor=east]{$\i$};
  10.      }
  11. \end{tikzpicture}
  • The keyword ‘node‘ tells TeX where we want to place our text. This is followed by some options and the what we want to display is placed in braces.
  • The anchor option is like alignment, for example on the x-axis we want the north side of the node to be positioned at the specified coordinate. This may be somewhat counter-intuitive so options like ‘above right‘ or ‘below‘ can be used instead.
  • Note that we can have verbatim text inside the boxes/nodes.
So what happens if we want fractions on our axis or multiples of π? In other words what if we want a “mathematical” tick there instead of just the “numeric” tick. It turns out TikZ can do this too:
  1. \begin{tikzpicture}[scale = 2]
  2.      \draw[step=0.2, style=gridstyle1] (-1,-1) grid (1,1);
  3.      \draw [->] (-1.2,0) — (1.2,0); \draw [->] (0,-1.2) — (0,1.2);
  4.      \foreach \i in {-1,-0.5, …, 1}{
  5.           \draw (\i,-0.05) — (\i,0.05);
  6.           \draw (-0.05,\i) — (0.05,\i);
  7.      }
  8.      \foreach \i/\itext in {-1, -0.5/-\frac{1}{2}, 0.5/\frac{1}{2}, 1}{
  9.           \draw (\i, 0) node[below] {$\itext$};
  10.           \draw (0, \i) node[left] {$\itext$};
  11.      }
  12. \end{tikzpicture}
  • This time when we write our for-loop we offer an alternate iterator (\itext), then where we use that alternate iterator inside the loop if an alternate definition is available it will use that instead. For example ‘0.5‘ has the alternate definition ‘\frac{1}{2}‘ so that will be used instead of ‘0.5‘ where \itext is used.
  • This is obviously a very simple example.
Putting Everything Together:
Lets put the circle and other elements back on the figure and label them too:
p, li { white-space: pre-wra
  1. \begin{tikzpicture}[scale = 4]
  2.      \def\R{0.8} % circle radius
  3.      \def\ANG{40} % the angle
  4.      \clip (-0.3,-0.3) rectangle (1.5,1.2);
  5.      \draw[step=0.2, style=gridstyle2] (-1,-1) grid (1,1);
  6.      \draw [->] (-1.2,0) — (1.2,0); \draw [->] (0,-1.2) — (0,1.2);
  7.      \draw (0,0) circle (\R);
  8.      \filldraw[fill=green!20!white, draw=green!50!black]
  9.           (0,0) — (0.3,0) arc (0:\ANG:0.3) — cycle;
  10.      \draw[red,very thick] (\ANG:\R) — node[left] {$\sin \alpha$} (\ANG:\R |- 0,0);
  11.      \draw[blue,very thick] (\ANG:\R |- 0,0) — node[below, midway] {$\cos \alpha$} (0,0);
  12.      \draw[very thick,orange] (\R,0) — node [right]
  13.           {$\displaystyle \tan \alpha \color{black}=
  14.           \frac{{\color{red}\sin \alpha}}{\color{blue}\cos \alpha}$}
  15.           (intersection of {\R,0–\R,\R} and {0,0–\ANG:\R})
  16.           coordinate (SAVE);
  17.      \draw (0,0) — (SAVE) ;
  18.      \foreach \i in {-1,-0.5, …, 1}{ % Draw the ticks
  19.           \draw (\i,-0.05) — (\i,0.05);
  20.           \draw (-0.05,\i) — (0.05,\i);
  21.      }
  22.      \foreach \i/\itext in {0, 0.5/\frac{1}{2}, 1}{ % add the y-axis labels
  23.           \draw (0, \i) node[left] {$\itext$};
  24.      }
  25.      \foreach \x in {0, 1}{ % add the x-axis labels
  26.           \draw (\x,0) node[below] {$\x$};
  27.      }
  28. \end{tikzpicture}
  • Lookin’ pretty good.
  • But there is one new thing that can be taken away: the coordinated at the end of the tangent line was saved using “coordinate (SAVE)“. This coordinate was then reused to draw the black radius line.

The next post on TikZ/PGF will look at drawing 3D diagrams.

References:

LaTeX Editors:

Ensure the following packages are installed:
$ sudo apt-get install texlive-fonts-recommended
$ sudo apt-get install texlive-fonts-extra

Advertisements