10

Is there an easy way to store the Euclidian distance between two coordinates?

I want to store the value 4 in a macro, so that I can use it to specify the width of a node.

The easiest way I could think of to to this is to somehow store the output of veclen(x,y) to a macro. I found this line in the tikz-pgf manual

\pgfmathparse{veclen(12,5)} \pgfmathresult

but I can't get it to work.

Does anyone have an idea? I found a couple of answers in this site that have something to do with calculating the distance between coordinates, but they always use the distance inside a specific path and don't store it in a macro to use it later.

Mico
  • 506,678
Florian
  • 515

3 Answers3

11

Here is a simple (?) code that computes the distance and stores it in a variable.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\makeatletter
\newcommand{\Distance}[3]{% % from https://tex.stackexchange.com/q/56353/121799
\tikz@scan@one@point\pgfutil@firstofone($#1-#2$)\relax  
\pgfmathsetmacro{#3}{round(0.99626*veclen(\the\pgf@x,\the\pgf@y)/0.0283465)/1000}
}% Explanation: the calc library allows us, among other things, to add and
% subtract points, so ($#1-#2$) is simply the difference between the points
% #1 and #2. The combination \tikz@scan@one@point\pgfutil@firstofone extracts
% the coordinates of the new point and stores them in \pgf@x and \pgf@y. 
% They get fed in veclen, and \pgfmathsetmacro stores the result in #3. 
% EDIT: included fudge factor, see https://tex.stackexchange.com/a/22702/121799
\makeatother
\begin{document}
\begin{tikzpicture}
\coordinate (X) at (1,0);
\coordinate (Y) at (3,0);
\draw[-] (X) -- (Y);
\node at (0,2) {\Distance{(X)}{(Y)}{\mylen}\mylen};
\end{tikzpicture}
\end{document}
  • Thanks, that works! I'll try to understand your code which may take me a while since I'm a beginner. – Florian Jan 30 '18 at 18:06
  • @Florian I added an explanation. –  Jan 30 '18 at 18:17
  • Thanks for adding the explaination.

    Is there a way to eliminate the rounding(?) error? veclen(1,-4) yields 4.12305, and your macro 4.13846.

    I dont' think the small difference matters for my use of the macro, I'm just curious.

    – Florian Jan 30 '18 at 18:23
  • @Florian Yes, see the update. –  Jan 30 '18 at 18:31
  • Great, thank you that's exactly what I was looking for :D – Florian Jan 30 '18 at 18:34
  • Why does the 6th line take away the units of the coordinates I give it, requiring you to convert to cm in the 7th line? I'm currently trying to get rid of the magic numbers in my code; otherwise I'd probably use this without hesitation. I want to be able to use something like whether my pictures use in, cm, mm, or anything else. – Pi Fisher Feb 28 '18 at 03:09
  • 1
    @PiFisher I am not sure if I understand your question, but internally TikZ is using points. \tikz@scan@one@point\pgfutil@firstofone gets the point (here defined as the difference between two points) and stores its coordinates in \pgf@x and \pgf@y, and the units used there are points. However, the OP wanted cm, that's why I convert. –  Feb 28 '18 at 04:19
4

Either calculate it manually using sqrt(x^2 + y^2) or use veclen as suggested:

enter image description here

\documentclass{article}

\usepackage{tikz}

\begin{document}

% Euclidian distance from (3, 4) to (12, 5)
\pgfmathparse{sqrt((12 - 3)^2 + (5 - 4)^2)}\pgfmathresult

% Euclidian distance from (3, 4) to (12, 5)
\pgfmathparse{veclen(12 - 3, 5 - 4)}\pgfmathresult

\end{document}

There is a rounding difference.

Werner
  • 603,163
3

For some particular cases you can also use a fit node. This way there's no need for storing the distance value.

\documentclass[tikz,border=2mm]{standalone} 
\usetikzlibrary{positioning, fit}

\begin{document}
\begin{tikzpicture}

\draw[fill=black] circle (1pt) node[below]{(0,0)} -- node[above]{4} ++(4,0) circle (1pt) node[below] {(4,0)};

\node[fit={(0,0) (4,0)}, inner xsep=0pt, draw, minimum height=1cm, anchor=south west] at (0,5mm) (a) {};
\end{tikzpicture}
\end{document}

enter image description here

Ignasi
  • 136,588