# Better way to calculate coordinates in Tikz?

I am great fan of pgf and tikz in general to produce great looking figures. But I don't like the amount of time I have to put in to draw a complicated picture, because I have to provide all the coordinates of the points lines etc. Is there any wrapper which makes this simpler? Like in some cases, eg when you have to put text over or around arrows, there are ways to give relative position instead of exact coordinates. Are there any similar ways to draw other shapes with relative coordinates? Is there any external program that can convert figures with lines and shapes into coordinates?

Complete LaTeX documents used to generate the figures in this answer are available as a Gist on GitHub.

One way to solve the "putting text over arrows" question is to use inline nodes and relative positioning:

\begin{tikzpicture}
\draw[->] (0,0) -- (5,0) node[above]{Hello, world!};
\end{tikzpicture} You can also use named nodes and coordinates combined with relative positioning. A \coordinate is just like a \node without a text area (they may still have shapes). Naming your nodes and coordinates allows you to re-use information about their position without re-typing the locations. Using relative positioning constructs (provided by the TikZ positioning library), like left = 1ex of A, allows you to position nodes/coordinates relative to other nodes/coordinates without working out the mathematics and geometry in your head.

\begin{tikzpicture}[
Name/.style = {font={\bfseries}}
]

\coordinate (A) at (0,0);
%            ^---- A name for the node/coordinate
\coordinate (B) at (5,1);
\coordinate (C) at (3,4);

\draw (A) -- (B) -- (C)  -- cycle;

\node (A-label) [left=1ex of A, Name] {A};
\node (B-label) [right=1ex of B, Name] {B};
\node (C-label) [above=1ex of C, Name] {C};

\node [above left = 2 em of C] {This is a relatively positioned node!}
edge[out=270,in=180,thick,->] (C-label);

\end{tikzpicture} See Tutorial 2 "A Petri-Net for Hagen" in the TikZ manual for an excellent step-by-step walkthrough of named nodes and relative positioning.

I prefer constructing figures using relative positioning as opposed to using a GUI program because I can change the look of the figure by adjusting the locations of a few "base coordinates". In this case, I could draw a completely different triangle by moving the locations of coordinates A, B and C and for most adjustments the rest of the figure would just fall into place. Learning to set up figures like this takes practice but once you get the it down it can save a bunch of time when it comes to fine-tuning the image when compared to a GUI program.

Finally, as to your question about GUI programs, I would recommend Inkscape- it is a very robust, open source editor for vector graphics that is similar to Adobe Illustrator. There is even a plugin available that generates TikZ code from Inkscape graphics.

• I have edited the question to remove some confusion in the wording of my question. Thanks for the descriptive answer. I will give Inkscape a try too. – Dash Aug 6 '10 at 22:32

jpgfdraw is a tool for freehand drawing and exporting to pgf. Perhaps see this jpgfdraw example, exported to pgf/tex and used with \input. Perhaps you could combine a freehand drawing with additional TikZ drawings.

• I was not aware of jpgfdraw. I will give it a try too. – Dash Aug 6 '10 at 22:33
• Bad name choice. I first thought that the tool exported to JPG! – Roberto Bonvallet Nov 16 '10 at 19:40

I think you need to be more specific in what you want to do. There are numerous ways to make relative coordinates in TikZ. Here are some Examples:

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\fill (1,1) circle (2pt) node[above] (O) {Start};
\draw (O) -- (2,2);   % absolute
\draw (O) --++ (3,2); % relative
\node[left=2cm] at (O) {Left}; % relative
\end{tikzpicture}

\end{document}


Check out http://www.texample.net/tikz/ for a lot of excellent examples of how to draw with TikZ.

• Thanks a lot. I was not aware of the --++ technique. I agree that texample is fantastic site I regularly use code from there. – Dash Aug 6 '10 at 22:30

There is a plugin for Inkscape, inkscape2tikz, that allows you to export TikZ code from Inkscape. It's been mentioned a few times already on other questions on this site.

\documentclass[11pt]{scrartcl}
\usepackage[utf8x]{inputenc}
\usepackage[upright]{fourier}
\usepackage{tikz,amsmath}
\usetikzlibrary{arrows,calc,shapes,decorations.pathreplacing}

\begin{document}
\begin{tikzpicture}

\node at (0,0) {$F : I \times I \rightarrow X$};
\node[label=below:$x_1$]  (x1) at (6,0)  {$\bullet$};
\node[label=above:$x_0$]  (x0) at (9,4)  {$\bullet$};
\node  at (9.5,2)  {$\subset X$};
\draw (x1.center) to [out=5,in=-90]++(2.8,1.8) to[out=90,in=-95](x0.center);
\draw (x1.center) to [out=10,in=-110]++(2.6,2) to[out=70,in=-103](x0.center);
\draw (x1.center) to [out=15,in=-105](x0.center);
\draw (x1.center) to [out=30,in=-150](x0.center);
\draw (x1.center) to [out=45,in=-170](x0.center);
\draw (x1.center) to [out=50,in=-105]++(1.2,3)to [out=75,in=-172](x0.center);
\draw (x1.center) to [out=55,in=-100]++(1.0,3) to[out=80,in=-175](x0.center);
\draw (x1.center) to [out=60,in=-90]++(0.8,3) to[out=90,in=-180] (x0.center);

\begin{scope}[every node/.style={draw, anchor=text, rectangle split, rectangle split parts=7,minimum width=2cm}]
\node (R) at (2,4){ \nodepart{two} \nodepart{three}\nodepart{four}$I\times I$\nodepart{five}\nodepart{six}\nodepart{seven}};
\end{scope}
\draw[decorate,decoration={brace,mirror,raise=6pt,amplitude=10pt}, thick] (R.north west)--(R.south west) ;
\draw[decorate,decoration={brace,raise=6pt,amplitude=10pt}, thick] (R.north east)--(R.south east);
\draw[->] ($(R.west)+(-20pt,0)$) to[out=-180,in=240] ++(0,2) to [out=60,in=120]node[above,midway]{$F(0,t_2)$}(x0) ;
\draw[->] ($(R.north)+(0,10pt)$) to [out=60,in=120]node[above,midway]{$\beta \simeq \alpha$} ++(4.5,-1) ;
\draw[->] ($(R.east)+(20pt,0)$)  to [out=0,in=140]node[right,midway]{$F(1,t_2)$}(x1) ;
\draw[->] ($(R.south)+(0,-20pt)$)  to [out=-85,in=-30]node[below,midway]{$\alpha$}++(7,0) ;
\end{tikzpicture}
\end{document} 