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 have a chart with relatively positioned nodes. How do I calculate the horizontal distance x, between node "sub3" and node "key" and multiply that value by 2 and use it for the positioning of node "bang2" such that it is aligned with node bang1.

I tried using some of the code from page 54 of the TikZ Manual v2.10 to draw a circle at node "sub3" with a radius reaching to node "bang2" as a test to see if I can calculate this, but it failed. I know that the TikZ example uses absolute positioning rather than relative positioning. I assume this is why my test failed.

\documentclass[12pt]{standalone}
\usepackage{fontspec}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning,shapes,backgrounds,fit,calc} 

\begin{document}

\begin{tikzpicture}[node distance=3cm, auto]  
\tikzset{
    mynode/.style={rectangle,rounded corners,draw=black, top color=white, bottom color=red!50,very thick, inner sep=1em, minimum size=3em, text centered},
    keynode/.style={rectangle,rounded corners,draw=black, top color=white, bottom color=orange!50,very thick, inner sep=1em, minimum size=3em, text centered},
    bangnode/.style={shape=star, star points=20, star point ratio=1.65,draw=black, top color=white, bottom color=yellow!50,very thick, inner sep=2em, minimum size=3em, text centered,font=\bfseries},
    myarrow/.style={->, >=latex', shorten >=1pt, thick},
    mylabel/.style={text width=7em, text centered} 
}  



\node[bangnode](bang1){Bang};
   \node[keynode,below left=2cm and 2cm of bang1](key){Key Message};
      \node[mynode,below right of=key](sub1){Sub Topic 1};
      \node[mynode,below of=sub1](sub2){Sub Topic 2};
      \node[mynode,below of=sub2](sub3){Sub Topic 3};
\node[bangnode,below right=2cm and 2cm of sub3](bang2){Bang};
%ARROWS
\draw[<->,bend left=45] (sub1)[]to(sub2);
\draw[<->,bend left=45] (sub2)to(sub3);
\draw[<->,bend left=45] (sub1)to (key);
\draw[<->,bend left=45] (sub2)to (key);
\draw[<->,bend left=45] (sub3)to (key);
%\draw (key) let 
          %   \p1 = ($ (sub3) - (key) $);
           % in
           %   circle ({veclen(\x1,\y1)});

\begin{pgfonlayer}{background}
    \node [fill=blue!10,fit=(bang1) (bang2) (sub1)(sub2)(sub3)(key)] {};
  \end{pgfonlayer}
\end{tikzpicture}

\end{document}

Chart

share|improve this question
    
Remove the semicolon in \p1 = ($ (sub3) - (key) $); and your code would work. –  percusse Nov 18 '12 at 23:19
add comment

1 Answer

up vote 10 down vote accepted

If all you want to do is to horizontally align the (bang1) and (bang2) nodes, you don't need such complicated calculations. You can use the let syntax to get the x-coordinate of (bang1) and the y-coordinate of (sub3), using something like

\path let \p1=(bang1), \p2=(sub3) in
node[bangnode,yshift=-2cm,anchor=north] (bang2) at (\x1,\y2) {Bang};

A complete example:

\documentclass[12pt]{standalone}
\usepackage{fontspec}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning,shapes,backgrounds,fit,calc} 

\begin{document}

\begin{tikzpicture}[node distance=3cm, auto]  
\tikzset{
    mynode/.style={rectangle,rounded corners,draw=black, top color=white, bottom color=red!50,very thick, inner sep=1em, minimum size=3em, text centered},
    keynode/.style={rectangle,rounded corners,draw=black, top color=white, bottom color=orange!50,very thick, inner sep=1em, minimum size=3em, text centered},
    bangnode/.style={shape=star, star points=20, star point ratio=1.65,draw=black, top color=white, bottom color=yellow!50,very thick, inner sep=2em, minimum size=3em, text centered,font=\bfseries},
    myarrow/.style={->, >=latex', shorten >=1pt, thick},
    mylabel/.style={text width=7em, text centered} 
}  



\node[bangnode](bang1){Bang};
   \node[keynode,below left=2cm and 2cm of bang1](key){Key Message};
      \node[mynode,below right of=key](sub1){Sub Topic 1};
      \node[mynode,below of=sub1](sub2){Sub Topic 2};
      \node[mynode,below of=sub2](sub3){Sub Topic 3};
\path let \p1=(bang1), \p2=(sub3) in
node[bangnode,yshift=-2cm,anchor=north] (bang2) at (\x1,\y2) {Bang};
%ARROWS
\draw[<->,bend left=45] (sub1)[]to(sub2);
\draw[<->,bend left=45] (sub2)to(sub3);
\draw[<->,bend left=45] (sub1)to (key);
\draw[<->,bend left=45] (sub2)to (key);
\draw[<->,bend left=45] (sub3)to (key);


\begin{pgfonlayer}{background}
    \node [fill=blue!10,fit=(bang1) (bang2) (sub1)(sub2)(sub3)(key)] {};
  \end{pgfonlayer}
\end{tikzpicture}

\end{document}

enter image description here

Another simpler option would be to use the perpendicular coordinate system, and use something like

\node[bangnode,yshift=-2cm,anchor=north] (bang2) at (bang1|-sub3) {Bang};

to place the node using the x-coordinate of (bang1) and the y-coordinate of (sub3). A complete example:

\documentclass[12pt]{standalone}
\usepackage{fontspec}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning,shapes,backgrounds,fit,calc} 

\begin{document}

\begin{tikzpicture}[node distance=3cm, auto]  
\tikzset{
    mynode/.style={rectangle,rounded corners,draw=black, top color=white, bottom color=red!50,very thick, inner sep=1em, minimum size=3em, text centered},
    keynode/.style={rectangle,rounded corners,draw=black, top color=white, bottom color=orange!50,very thick, inner sep=1em, minimum size=3em, text centered},
    bangnode/.style={shape=star, star points=20, star point ratio=1.65,draw=black, top color=white, bottom color=yellow!50,very thick, inner sep=2em, minimum size=3em, text centered,font=\bfseries},
    myarrow/.style={->, >=latex', shorten >=1pt, thick},
    mylabel/.style={text width=7em, text centered} 
}  



\node[bangnode](bang1){Bang};
   \node[keynode,below left=2cm and 2cm of bang1](key){Key Message};
      \node[mynode,below right of=key](sub1){Sub Topic 1};
      \node[mynode,below of=sub1](sub2){Sub Topic 2};
      \node[mynode,below of=sub2](sub3){Sub Topic 3};
\node[bangnode,yshift=-2cm,anchor=north] (bang2) at (bang1|-sub3) {Bang};
%ARROWS
\draw[<->,bend left=45] (sub1)[]to(sub2);
\draw[<->,bend left=45] (sub2)to(sub3);
\draw[<->,bend left=45] (sub1)to (key);
\draw[<->,bend left=45] (sub2)to (key);
\draw[<->,bend left=45] (sub3)to (key);


\begin{pgfonlayer}{background}
    \node [fill=blue!10,fit=(bang1) (bang2) (sub1)(sub2)(sub3)(key)] {};
  \end{pgfonlayer}
\end{tikzpicture}

\end{document}

And, to answer the specific question, of course you can calculate distances between nodes, using veclen and the let syntax; a simple example:

\documentclass[12pt]{article}
\usepackage{tikz}
\usetikzlibrary{positioning,calc} 

\begin{document}

\begin{tikzpicture}
\node (A) {A};
\node[below left=of A ] (B) {B};
\node[below =of B ] (C) {C};
\node[below right =of C ] (D) {D};
\draw (B) -- (D);
\draw (B) let \p1 = ($ (D) - (B) $)
  in circle ({veclen(\x1,\y1)});
\end{tikzpicture}

\end{document}

enter image description here

In the original code:

\draw (key) let 
  \p1 = ($ (sub3) - (key) $);
  in
  circle ({veclen(\x1,\y1)});

there's a superfluous semicolon at the end of the second line; once this is removed:

\draw (key) let 
  \p1 = ($ (sub3) - (key) $)
  in
  circle ({veclen(\x1,\y1)});

the code should work.

share|improve this answer
    
Cool! Great answer...almost there... my question was, could you calculate the difference between two relatively positioned nodes. Your examples do not do any calculations, they just assign x,y coordinates. Nonetheless, thanks for putting in an alternative too. Keep in mind, the point is not to align bang1 and bang2 (although it is nice to do so), the point is to learn how to make calculations between relative points. –  macmadness86 Nov 18 '12 at 23:07
    
@macmadness86 please see my updated answer for an example of calculation of distance between nodes. –  Gonzalo Medina Nov 18 '12 at 23:18
    
I hate to do this, because you made a nice-looking answer... but my question is: how do I calculate the distance between RELATIVE points. Point A in your example is fixed at (0,0). Maybe I should rephrase my question. Could I use a relatively positioned node as a reference point for my calculations? –  macmadness86 Nov 18 '12 at 23:27
    
@macmadness86 the idea is the same independently of whether the nodes are placed absolutely or relatively; I updated my last example. –  Gonzalo Medina Nov 18 '12 at 23:34
    
That is what I wanted to know! Thanks! Could you also tell me why may commented out calculation in gray is not working? It looks the same as your example to me... What am I missing? –  macmadness86 Nov 18 '12 at 23:44
show 2 more comments

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.