2

I am using TikZ automata to draw a roted tree digraph. I'd like to use a \froeach loop at every node to build the next generation (in polar coordinates relative to tha actual node). Thus, it would be convenient to change the origin of the polar coordinate system before each loop. How can this be done?

Below is a MWE corresponding to the first generation:

\documentclass{standalone}
\usepackage{tikz,tkz-graph}
\usetikzlibrary{automata,positioning,decorations.markings}

\begin{document}

\newcount\mycount
\begin{tikzpicture}[shorten >=1pt, node distance=0.5 and 1.75, on grid,auto,>=stealth']
  \node[state] (q1) {};
   %\node[] (Q1) [above = 0.35 of q1] {}

  \foreach \number in {1,...,2}{
      % Computer angle:
        \mycount=\number
        \advance\mycount by -1
  \multiply\mycount by 40
        \advance\mycount by 0
      \node[state] (p\number) at (215+\the\mycount:1.5cm) {};
    }

    \node[state] (pk) at (325+\the\mycount:1.5cm) {};

    \path[->]
        (q1) edge[]
            (p1);

    \path[->]
        (q1) edge[]
            (p2);

    \path[->]
        (q1) edge[]
            (pk);

\end{tikzpicture}
\end{document}

I'd like to repeat the previous scheme at every (descendant) node. I have seen in related questions that one can use ++ to change the current reference point, bu t I don't see how to use it in my case.

Thank you.

  • @JLDuaz Sorry, you are right. I'll fix that now. – suitangi Feb 16 '17 at 10:25
  • You can use \begin{scope}[shift={(angle:distance)}]` to create a scope in which the origin will be shifted (until \end{scope}. But I don't still see clearly the intended result. Do you want recursively descend by the nodes? Up to which depth? – JLDiaz Feb 16 '17 at 10:31
  • JLDiaz I (hopefully) have fixed the code. I avoided the main loop just in order to simplify the example. It would be enough to repeat the \foreach loop at any different node. – suitangi Feb 16 '17 at 10:32
  • @JLDiaz OK, just suppose that I want to draw two different nodes with 27 and 28 descendants. How to change the origin of the polar coordinate system for drawing the descendants of the second node? – suitangi Feb 16 '17 at 10:36
  • @JLDiaz by the way, I would appreciate If you can mention how to to simplify the loop using tikz expressions. – suitangi Feb 16 '17 at 10:46
1

Update

(See Original for previous response)

After better understanding the OP goals, I think that the best approach would be to use some of the TikZ solutions for drawing graphs and tress, such as the algorithmic graph drawing introduced in latest TikZ version (this approach, however, requires to use LuaLaTeX to compile).

If you prefer to create the graph yourself using loops, the following example can be useful. It first creates the parent node and three children named p1, p2 and pk. The angles at which these children spawn from the parent are given as arguments, instead to be computed, to have finer control and avoid overlapping. However, in a more general case, I guess they should be computed depending on the number of children.

Once these nodes are in place, a loop iterates over the children names, and for each one it draws the edge with the parent, and creates a new subtree, using tikz calc to set the child as the new origin, as the expression ($(\p)+(\angle:1cm)$), in which \p is the name of the child and \angle a loop variable for the subtree.

This is the code:

\documentclass[border=5pt]{standalone}
\usepackage{tikz,tkz-graph}
\usetikzlibrary{calc}
\usetikzlibrary{automata,positioning}

\begin{document}
\begin{tikzpicture}[shorten >=1pt, node distance=0.5 and 1.75, on grid,auto,>=stealth']
    \node[state] (q1) {};
    % Generate children nodes p1, p2 and pk
    \foreach \angle\name in {205/p1,260/p2,325/pk}{
        \node[state] (\name) at (\angle:1.5cm) {};
    }
    % For each of those children
    \foreach \p in {p1,p2,pk} {
      \path[->] (q1) edge[] (\p);    % Draw the edge between parent and children
      % And draw a subtree
      \foreach \angle [count=\n from 1] in {235,255,295} { 
           \node[state, minimum size=1] (\p\n) at ($(\p)+(\angle:1cm)$) {};
           \path[->] (\p) edge[] (\p\n);
       }
    }
\end{tikzpicture}
\end{document}

This is the result:

Result

Original

I hope the next MWE will give you some hint for solving your problem, since I'm not confident of having understood it completely.

This code simplifies your code in the computation of the angle at which each node is drawn, making unnecessary your counter \mycount and the use of TeX's counter arithmetic. I use instead TikZ loop counter and tikz arithmetic expressions.

In addition, I enclose the drawing of the little tree inside a tikz scope, which uses shift property to change the origin.

To demonstrate the result, I created an external loop which changes this origin placing it at four different locations and draws the little tree at each location. I added some red lines to help visualize the position of each new origin.

This is the code:

\documentclass{standalone}
\usepackage{tikz,tkz-graph}
\usetikzlibrary{calc}
\usetikzlibrary{automata,positioning,decorations.markings}
\def\gpi{\mathrm{gpi}}

\begin{document}


\begin{tikzpicture}[shorten >=1pt, node distance=0.5 and 1.75, on grid,auto,>=stealth']

\foreach \angle in {-160, -60, 0, 60} {
  \draw[red, dotted] (0,0) -- (\angle:3);
  \begin{scope}[shift={(\angle:3)}]
    \node[state] (q1) {};
    \foreach \number [count=\count from 0] in {1,...,2}{
       \node[state] (p\number) at (215+\count*40:1.5cm) {};
    }
    \node[state] (pk) at (295+\count*40:1.5cm) {};
    \path[->]   (q1) edge[]   (p1);
    \path[->]   (q1) edge[]   (p2);
    \path[->]   (q1) edge[]   (pk);
  \end{scope}
}
\end{tikzpicture}
\end{document}

This is the result:

Result

| improve this answer | |
  • Ok, I am afraid that my question was misleading. The point is that the final graph is not necessarily regular, and I need a loop for every expanding node (this is why I was asking how to change the polar origin). Sorry again! – suitangi Feb 16 '17 at 10:59
  • 1
    @suitangi you can also use tikz calc package, which will allow you to use complex expressions for coordinates, such as for example \node at ($(p1)+(215:1.5cm)$) {}; to compute a coordinate relative to (p1). – JLDiaz Feb 16 '17 at 11:03
  • I think this is exactly what I was asking for. Are you so kind to update your answer with the previous comment? – suitangi Feb 16 '17 at 11:15
  • @suitangi See the updated answer. I hope this new approach is useful to you. – JLDiaz Feb 16 '17 at 12:00

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.