# TikZ: How to determine the vector between two co-ordinates

Given two co-ordinates say, X.south east and X.south west, is it possible to determine the length or the vector between the two?

In the MWE the width, has been calculated using traditional TeX techniques, but is obviously a bit of a wasted effort as PGF probably did all these calculations already.

\documentclass{article}
\usepackage{pgf,tikz}
\makeatletter
\begin{document}
\def\convert@cx#1{\the#1}
\newlength\xheight@cx
\newlength\xlength@cx
\newlength\xdepth@cx
\newlength\xtotal@cx
\newsavebox{\fontbox}
%
\def\drawfontbox#1{%
{\upshape\Huge
\savebox{\fontbox}{#1}
\pgfmathsetlength{\xheight@cx}{\ht\fontbox}
\pgfmathsetlength{\xlength@cx}{\wd\fontbox}
\pgfmathsetlength{\xdepth@cx}{\dp\fontbox}
\pgfmathsetlength{\xtotal@cx}{\xdepth@cx+\xheight@cx}
\begin{tikzpicture}[scale=1]
\node[rectangle,draw,inner sep=0pt,outer sep=0pt] (X){#1};
\draw[red, line width=0.4pt] (X.text)  circle(1pt)[fill=red] -- (X.base east);
\draw[|<->|,>=latex] ([yshift=5pt] X.north west)
--([yshift=5pt] X.north east) node [above=-5pt,midway,
font={\tiny}]{width = \convert@cx{\xlength@cx}};
% draw the xheight
\draw[|<->|,>=latex]([xshift=-5pt]X.base west)
--([xshift=-5pt] X.north west)
node [left,midway,font={\tiny}] {x-height=\convert@cx{\xheight@cx}};
%   draw depth
\draw[-|,>=latex]([xshift=-5pt]X.base west)
--([xshift=-5pt] X.south west)
node [left,midway,font={\tiny}] {depth=\convert@cx{\xdepth@cx}};
\draw[<-,>=latex]([xshift=-5pt]X.south west)
--++(0,-8pt);
%   draw total height
%
\draw[|<->|,>=latex]([xshift=5pt]X.north east)
--([xshift=5pt] X.south east)
node [right,midway,font={\tiny}] {height=\convert@cx{\xtotal@cx}};
\end{tikzpicture}}
}
\drawfontbox{QWERTY}
\end{document}

-
Does \veclen not work in this context? – Peter Grill Jun 2 '12 at 15:34
@PeterGrill \veclen might or might not work, but currently it is neither in my memory nor in my vocabulary. Maybe you can provide an answer? – Yiannis Lazarides Jun 2 '12 at 15:38
\veclen gives the "length" of the vector. You get the coordinates of the vector with TeX : \pgfpointdiff{\pgfpointanchor{A}{anchor}}{\pgfpointanchor{B}{anchor}} in \pgf@x and \pgf@y. Another possibility is ($(b)-(a)$) for example \node (c) at ($(b)-(a)$) {c}; – Alain Matthes Jun 2 '12 at 15:43
@Altermundus Thanks a lot will check them in the manual. – Yiannis Lazarides Jun 2 '12 at 15:46
\pgfpointdiff{⟨start ⟩}{⟨end ⟩} Returns the difference vector ⟨end⟩ − ⟨start⟩. – Alain Matthes Jun 2 '12 at 15:47

An example with let and veclen:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (4,2);
\draw let
\p1 = (a),
\p2 = (b),
\n1 = {veclen((\x2-\x1),(\y2-\y1))}
in
(a) to[sloped,above] node{\n1} (b);
\end{tikzpicture}

\end{document}


\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\def\drawfontbox#1{%
\begin{tikzpicture}[%
MyArr/.style={|<->|,>=latex},
MyLabel/.style={font={\tiny}}]
\node[rectangle,draw,inner sep=0pt,outer sep=0pt] (X){\Huge #1};
\draw
let
\p1 = (X.base west),
\p2 = (X.south west),
\p3 = (X.south east),
\p4 = (X.north west),
\p5 = (X.north east),
\n1 = {veclen(\x5-\x4,\y5-\y4)}, % width
\n2 = {veclen(\x5-\x3,\y5-\y3)}, % height
\n3 = {veclen(\x4-\x1,\y4-\y1)}, % x-height
\n4 = {veclen(\x2-\x1,\y2-\y1)}  % depth
in
([yshift=5pt] X.north west)
edge[MyArr] node [above=-1pt,MyLabel]{width = \n1}
([yshift=5pt] X.north east)
([xshift=-5pt]X.base west)
edge[MyArr] node [left,MyLabel] {x-height=\n3}
([xshift=-5pt] X.north west)
([xshift=-5pt]X.base west)
edge[-|,>=latex] node [left,MyLabel] {depth=\n4}
([xshift=-5pt] X.south west)
([xshift=5pt]X.north east)
edge[MyArr] node [right,MyLabel] {height=\n2}
([xshift=5pt] X.south east)
;
\draw[red, line width=0.4pt] (X.text)  circle(1pt)[fill=red] -- (X.base east);
\end{tikzpicture}
}
\begin{document}
\drawfontbox{QWERTY}

\drawfontbox{Lorem Ipsum}

\drawfontbox{What?}
\end{document}

-
Nice and neat, thanks. – Yiannis Lazarides Jun 3 '12 at 9:17

Perhaps this answer will be useful, i f you want the dimensions of a TeX box

\documentclass{article}
\usepackage{tikz}

\begin{document}
\newsavebox{\ftbox}
\savebox{\ftbox}{\Huge QWERTY}

\pgfmathparse{width("\usebox\ftbox")} \pgfmathresult

\pgfmathparse{height("\usebox\ftbox")} \pgfmathresult

\pgfmathparse{depth("\usebox\ftbox")} \pgfmathresult
\end{document}


-
the same is possible with simple TeX commands: \the\wd\ftbox, \the\ht\ftbox, and \the\dp\ftbox ... – Herbert Jun 2 '12 at 17:40
Yes Herbert, you are right but it's only to note the existence of these functions and it's possible to use these functions in other cases. For example width("qwerty") it's not necessary to use the box. – Alain Matthes Jun 2 '12 at 17:55

And as Altermundus commented, yet another one to use with arbitrary rectangular nodes :) Add more custom lengths as you wish.

\documentclass{article}
\usepackage{tikz}
\makeatletter
\newcommand{\anchordistances}[1]{
\pgfpointdiff{\pgfpointanchor{#1}{base}}{\pgfpointanchor{#1}{south}}\pgfmathsetmacro{\mydepth}{veclen(\pgf@x,\pgf@y)}
\pgfpointdiff{\pgfpointanchor{#1}{north west}}{\pgfpointanchor{#1}{north east}}\pgfmathsetmacro{\mywidth}{veclen(\pgf@x,\pgf@y)}
\pgfpointdiff{\pgfpointanchor{#1}{south west}}{\pgfpointanchor{#1}{north west}}\pgfmathsetmacro{\myheight}{veclen(\pgf@x,\pgf@y)}
\pgfpointdiff{\pgfpointanchor{#1}{base}}{\pgfpointanchor{#1}{north}}\pgfmathsetmacro{\myxheight}{veclen(\pgf@x,\pgf@y)}
}
\makeatother

\begin{document}
\begin{tikzpicture}
\node[draw,inner sep=0,outer sep=0] (X) {\upshape\Huge QWERTY};
\draw[red, line width=0.4pt] (X.text)  circle(1pt)[fill=red] -- (X.base east);
\anchordistances{X}

% draw the xheight
\draw[|<->|,>=latex]([xshift=-5pt]X.base west)
--([xshift=-5pt] X.north west)
node [left,midway,font={\tiny}] {x-height=\myxheight};
\draw[-|,>=latex]([xshift=-5pt]X.base west)
--([xshift=-5pt] X.south west)
node [left,midway,font={\tiny}] {depth=\mydepth};
\draw[<-,>=latex]([xshift=-5pt]X.south west)
--++(0,-8pt);

\draw[|<->|,>=latex] ([yshift=5pt] X.north west)
--([yshift=5pt] X.north east) node [above,midway,
font={\tiny}]{width = \mywidth};
\draw[|<->|,>=latex]([xshift=5pt]X.north east)
--([xshift=5pt] X.south east)
node [right,midway,font={\tiny}] {height=\myheight};
\end{tikzpicture}
\end{document}


Hmm, I forgot the pt units.

-
\documentclass{article}
\def\getVLength(#1,#2)(#3,#4){%
\directlua{tex.print(math.sqrt((#3-#1)^2+(#4-#2)^2))}}

\begin{document}
\getVLength(0,0)(4,2)
\end{document}


run with lualatex

-