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.

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.

enter image description here

\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}
share|improve this question
1  
Does \veclen not work in this context? –  Peter Grill Jun 2 '12 at 15:34
1  
@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
1  
\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
show 1 more comment

4 Answers

up vote 17 down vote accepted

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}

enter image description here

An adaption of your original code:

enter image description here

\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}
share|improve this answer
    
Nice and neat, thanks. –  Yiannis Lazarides Jun 3 '12 at 9:17
add comment

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} 

enter image description here

share|improve this answer
    
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
add comment

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}

enter image description here

Hmm, I forgot the pt units.

share|improve this answer
add comment
\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

share|improve this answer
add comment

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.