Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I asked a question before about how to position a node relative to another node at a certain angle in TikZ, and the answer I got there was that you can use the \path (node1) ++(angle:distance) node [styles] (node2) {}; syntax.

However, the distance here only concerns the distance between the centers of the two nodes, and not the distances between the outer edges of the nodes. To illustrate, look at the example below:

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{positioning}

\newdimen\nodeSize
\nodeSize=4mm
\newdimen\nodeDist
\nodeDist=6mm
\begin{document}
\begin{tikzpicture}[
    node/.style={%
      draw,
      circle,
      inner sep=0,
      outer sep=0,
      minimum size=\nodeSize,
      node distance=\nodeDist,
    },
  ]
  \node [node] (n1) {$n_1$};
  \node [node, below=of n1] (n2) {$n_2$};
  \path (n2) ++(-120:\nodeDist) node [node] (n3) {$n_3$};
  \path (n2) ++(- 60:\nodeDist) node [node] (n4) {$n_4$};

  \draw (n1) -- (n2);
  \draw (n2) -- (n3);
  \draw (n3) -- (n4);
  \draw (n4) -- (n2);
\end{tikzpicture}
\end{document}

enter image description here

An easy fix is of course to let the distance be the sum of \nodeDist and \nodeSize, but I'm wondering if there is some more robust way of doing this such that:

  1. it uses the value of node distance (thereby not having to deal with lengths external to TikZ), and
  2. takes the actual sizes of the nodes into account.

Ideally, it would be nice to be able to enable a similar method as provided by the positioning library - \node [position=60 degrees from node1] (node2) {}; - or something like it.

share|improve this question

1 Answer 1

up vote 6 down vote accepted

You can achieve something like this relatively easily by defining a new style

position/.style args={#1:#2 from #3}{
    at=(#3.#1), anchor=#1+180, shift=(#1:#2)
}

Then you can specify the angle and the separation between the nodes using, for example, position=-120:{\nodeDist} from n2.

If you want to use the value set in node distance, you can use

\makeatletter
\tikzset{
    position/.style args={#1 degrees from #2}{
        at=(#2.#1), anchor=#1+180, shift=(#1:\tikz@node@distance)
    }
}
\makeatother

and call the style using position=120 degrees from n2

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{positioning}

\newdimen\nodeSize
\nodeSize=4mm
\newdimen\nodeDist
\nodeDist=6mm

\tikzset{
    position/.style args={#1:#2 from #3}{
        at=(#3.#1), anchor=#1+180, shift=(#1:#2)
    }
}

\begin{document}
\begin{tikzpicture}[
    node/.style={%
      draw,
      circle,
      inner sep=0,
      outer sep=0,
      minimum size=\nodeSize,
      node distance=\nodeDist,
    },
  ]
  \node [node] (n1) {$n_1$};
  \node [node, below=of n1] (n2) {$n_2$};
  \node [node, position=-120:{\nodeDist} from n2] (n3) {$n_3$};
  \node [node, position=-60:{\nodeDist} from n2] (n4) {$n_4$};

  \draw (n1) -- (n2);
  \draw (n2) -- (n3);
  \draw (n3) -- (n4);
  \draw (n4) -- (n2);
\end{tikzpicture}
\end{document}
share|improve this answer
1  
This is so ingenious! Very clever and user-friendly! Thank you! –  gablin Mar 13 '13 at 13:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.