# Using Tikz package to extracting length, coordinates and assigning them to variables

The code below is extracted from:

"\internalforces" command in stanli package

(code exam1b - The second coding set in this example)

and

Using reference points in "Stanli"

Is there a way to use a combination of those 2 macros so as to

• be able to extract line lengths assigning them to a variable So that I may be capable of using such variable as an input for other operations later on?

• Set extracted line lengths to be in cm, inch .... or whatever unit is required

• be able to extract point coordinates and assigning them to a variable So that I may be capable of using such variable as an input for other operations later on?

Here is the MWE


\documentclass[tikz,varwidth,border=3.14mm]{standalone}
\usepackage[a4paper,top=2.5cm,bottom=2.5cm,margin=2.5cm,bindingoffset=0.5cm]{geometry}

\usepackage[bidi=basic,layout=lists.tabular]{babel}
\babelfont[english]{rm}{Times New Roman}

\usepackage{amsmath}
\usetikzlibrary{calc,decorations.pathreplacing}

\newcommand\DeclareConstant[2]{%
\pgfkeys{/MyStuff/declare constant={#1}{#2}}%
}%
\newcommand\DeclareConstants[1]{\pgfkeys{/MyStuff/.cd,#1,}}%
\newcommand\exchangeargs[2]{#2#1}%
\makeatletter
\pgfkeys{%
/MyStuff/.unknown/.code=\pgfkeys{/MyStuff/declare constant={\pgfkeyscurrentname}{#1}},
/MyStuff/declare constant/.code 2 args=%
\begingroup
\pgfmathparse{#2}%
\ifcat$\detokenize{#1}$\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{%
\GenericError{\space\space\@spaces\@spaces\@spaces\@spaces\@spaces\@spaces\@spaces}%
{Constant declaration error: Name of constant not specified}%
{\space\space\@spaces\@spaces\@spaces\@spaces\@spaces\@spaces\@spaces You cannot declare a constant without\MessageBreak specifying its name.}%
{You need some sort of identifier for referencing the constant.}%
\ifcat$\detokenize\expandafter{\pgfmathresult}$\expandafter\@firstofone\else\expandafter\@gobble\fi
{%
\GenericError{\space\space\@spaces\@spaces\@spaces\@spaces\@spaces\@spaces\@spaces}%
{Constant declaration error: Value of constant not specified}%
{\space\space\@spaces\@spaces\@spaces\@spaces\@spaces\@spaces\@spaces You cannot declare a constant without\MessageBreak specifying its value.}%
{Which aspect of a constant could be constant if not its value?\MessageBreak So there must be a value!}%
}%
\endgroup
}{%
\ifcat$\detokenize\expandafter{\pgfmathresult}$\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{%
\GenericError{\space\space\@spaces\@spaces\@spaces\@spaces\@spaces\@spaces\@spaces}%
{Constant declaration error: Value of constant not specified}%
{\space\space\@spaces\@spaces\@spaces\@spaces\@spaces\@spaces\@spaces You cannot declare a constant without\MessageBreak specifying its value.}%
{Which aspect of a constant could be constant if not its value?\MessageBreak So there must be a value!}%
\endgroup
}{%
\expandafter\endgroup
\expandafter\exchangeargs\expandafter{\expandafter{%
\expandafter\def
\expandafter\pgfmathresult
\expandafter{\pgfmathresult}%
}}{\pgfmathdeclarefunction*{#1}{0}}%
}%
},%
/MyStuff/declare constant/.value required,%
}%
\makeatother

\begin{document}

% \DeclareConstant{Y1}{-3-3};
% \DeclareConstant{Y2}{-14};
\DeclareConstants{
Y1=-3-1-2,              % yields Y1=-6
Y2={mod(-114,-100)},    % yields Y2=-14
% Y3=...,
% Y4=...,
% foobar=...,
% ...
};

\def\xa{1}
\def\ya{1}
\def\xb{2}
\def\yb{2}
%
\begin{equation*}
c=
\begin{cases}
x_c=\xnewResults
\\
y_c=\ynewResults
\end{cases}
\end{equation*}
%
\def\num{.5}
\def\xa{1}
\def\ya{1}
\def\xb{0.63397}
\def\yb{2.36603}
%
\begin{equation*}
P_{Ac}=
\begin{cases}
x_p=\xpointResults
\\
y_p=\ypointResults
\end{cases}
\end{equation*}
\end{document}


• @Ulrich Diez, For example, Upon drawing a line joining 2 nodes or between 2 coordinates, in order to use the length of such line in further calculations,how am i to extract the length of that line and assign it to a variable. How can I extract the distance between any 2 nodes or coordinates, store them in a variable for further use..... How to Extract data from various components (Especially lengths and coordinates) and assigning them to a variable. – Silva Oct 30 '20 at 18:15
• Note the code exam1b \path let \p{1} = (c) in (c) node[yshift=2mm,label=above:\tiny\pgfmathparse{\x1/28.45274}${x_c=}\pgfmathresult$]{} circle (0pt)node[label=above:\tiny\pgfmathparse{\y1/28.45274}${y_c=} \pgfmathresult$]{}; – M.Ahmadi Oct 31 '20 at 17:23

The distance between two points can be calculated according to the rules of vector calculation.

The problem with TikZ is:

TikZ is a means for drawing things on paper.

More abstract:

TikZ is used to visualize/depict whatsoever facts by means of a two-dimensional plane.

For this purpose TikZ internally uses for each tikzpicture a plane which is spanned by a two-dimensional Cartesian coordinate system, whose base vectors are perpendicular to each other and are 1pt long. (According to TeXbook, chapter 10: 72.27pt = 2.54cm <-> (72.27/2.54)pt = 1cm)

All location data/all coordinates provided via user-input, e.g., things like \coordinate (AB) at (1.25,0.25);, are internally immediately transformed by TikZ to its internal coordinate system.

Even if you want to display something three-dimensional, using x-, y- and z-coordinates, the three-dimensional coordinates are immediately transformed into the two-dimensional coordinates internally used for drawing the depiction.

The circumstance that everything is transformed immediately implies that TikZ itself only keeps data that are related to the depiction/image to be created.
Data related to the facts themselves, which are represented by the depiction, is not held in stock by TikZ.

By means of the data kept by TikZ itself you can, e.g., conclude how long a line is which is a component of the depiction.

But from the data, which TikZ itself stores, one can conclude only very limited on data, e.g., values of physical or other quantities, which belong to the facts themselves, which are to be depicted.

If, for example, you draw a three-dimensional pyramid by means of TikZ, you can use the data held in stock by TikZ itself to calculate how long the line in the depiction is which in the depiction represents the height of the pyramid. This refers to the depiction. The height of the three-dimensional pyramid itself cannot be calculated with these data. This is because the data provided by TikZ refers to the depiction, i.e., to something two-dimensional, whereas the pyramid is a three-dimensional object. In the data stock of TikZ itself, information is missing, which refers to the three-dimensionality of the object to be depicted.

To base calculations, which refer to the facts to be represented, on data, which are kept in stock by the TikZ package itself, is—in my humble opinion—the wrong approach.

Instead, specify yourself all quantities that you want to depict and whose values are to be displayed in the depiction.

When specifying these quantities you can of course use \pgfmathparse to have things calculated. However, be aware that \pgfmathparse often calculates in ways that produce small rounding errors/conversion errors.

E.g., if you put the length 1.5cm into \pgfmathparse—i.e., \pgfmathparse{1.5cm}, as result the numerical value of this quantity will be stored in the macro in \pgfmathresult, standardized to the unit 1pt. If you want to have the numerical value of this quantity standardized to the unit 1cm and therefore do \pgfmathparse{scalar((\pgfmathresult)*(1pt/1cm))}, then the result will not be 1.5 but will be something like 1.49979:

\documentclass{article}
\usepackage{stanli}
\pgfmathparse{1.5cm}
\show\pgfmathresult % 42.67912 - this is a scalar, the numerical value of the quantity 1.5cm standardized to the unit 1pt, with rounding-error.
\pgfmathparse{scalar((\pgfmathresult)*(1pt/1cm))}
\show\pgfmathresult % 1.49979 - this is a scalar, the numerical value of the quantity 42.67912pt standardized to the unit 1cm, also with rounding-error.
\stop


If you intend to do calculations with the data held in stock by TikZ within the scope of the tikzpicture itself in order to do things related to the depiction, you can obtain xy-coordinates (numerical values of coordinates normalized to 1pt), e.g., by doing something like this:

You need to keep in mind that things that should not be understood by \pgfmathparse as mathematical operators or as names of mathematical functions, e.g., names of "coordinates", have to be put between " when occurring in the argument of \pgfmathparse/when occurring in things that get processed by \pgfmathparse.

By the way, I think in TikZ a \coordinate being composed of x-, and y- (and z-) values is very strange. In common usage, for example an x-value is itself a coordinate and not a component of a coordinate.

\documentclass{article}
\usepackage{stanli}
\csname @ifundefined\endcsname{pagewidth}{}{\pagewidth=\paperwidth}%
\csname @ifundefined\endcsname{pdfpagewidth}{}{\pdfpagewidth=\paperwidth}%
\csname @ifundefined\endcsname{pageheight}{}{\pageheight=\paperheight}%
\csname @ifundefined\endcsname{pdfpageheight}{}{\pdfpageheight=\paperheight}%
\textwidth=\paperwidth
\oddsidemargin=2.5cm
\marginparsep=.2\oddsidemargin
\marginparwidth=\oddsidemargin
\evensidemargin=\oddsidemargin
\textheight=\paperheight
\topmargin=2.5cm
\footskip=.5\topmargin
\pagestyle{plain}
\parindent=0ex
\parskip=0ex
\topsep=0ex
\partopsep=0ex

\pgfmathdeclarefunction{StandardizeToUnit}{2}{%
\begingroup
\pgfmathparse{scalar((#1)*((1pt)/(#2)))}%
\pgfmathsmuggle\pgfmathresult\endgroup
}%
\pgfmathdeclarefunction{XCoordinate}{1}{%
\begingroup
\path(#1);\pgfgetlastxy{\XCoord}{\YCoord}%
\pgfmathparse{\XCoord}%
\pgfmathsmuggle\pgfmathresult\endgroup
}%
\pgfmathdeclarefunction{YCoordinate}{1}{%
\begingroup
\path(#1);\pgfgetlastxy{\XCoord}{\YCoord}%
\pgfmathparse{\YCoord}%
\pgfmathsmuggle\pgfmathresult\endgroup
}%

\begin{document}

\noindent
\begin{tikzpicture}

\coordinate (O) at (0,0);
\coordinate (A) at (1,1);
\coordinate (B) at (1,2);
\coordinate (C) at (2,2);
\coordinate (D) at (2,1);

\draw (A) node[below left]{A} -- (B) node[above left]{B} -- (C) node[above right]{C} -- (D) node[below right]{D} -- cycle;
\draw (O) node[below left]{origin};
\foreach \element in {A,B,C,D,O} \fill (\element) circle (2pt);

\draw[->] (-3,0) -- (3,0)node[right]{\lower-.5ex\hbox{x-direction}};
\draw[->] (0,-3) -- (0,3)node[above]{y-direction};

% TikZ-data like \coordinate (A)... is not available outside the tikzpicture, therefore let's save
% coordinates to macros:

\pgfmathparse{XCoordinate("A")}
\global\let\Ax=\pgfmathresult
\pgfmathparse{YCoordinate("A")}
\global\let\Ay=\pgfmathresult
\pgfmathparse{XCoordinate("C")}
\global\let\Cx=\pgfmathresult
\pgfmathparse{YCoordinate("C")}
\global\let\Cy=\pgfmathresult

\end{tikzpicture}

\bigskip
\hrule
\bigskip

A was specified as: \verb|\coordinate (A) at (1,1);|

This means:

In order to determine the coordinates of A in the tikzpicture add one time TikZ's x-vector and one time TikZ's y-vector to the origin.\\
(At the time of specifying A/determining the coordinates of A in TikZ's internal coordinate system
\begin{itemize}
\item the x-vector was specified to point as many pt in x-direction as correspond to 1cm and to point 0pt in y-direction.
\item the y-vector was specified to point as many pt in y-direction as correspond to 1cm and to point 0pt in x-direction.
\end{itemize}%
The x-vector and the y-vector and the z-vector can be adjusted via \verb|\pgfsetxvec| respective \verb|\pgfsetyvec| respective \verb|\pgfsetzvec|.)

\bigskip

The x-coordinate $A_x$ of A in TikZ's internal coordinate system of the corresponding tikzpicture is:  \Ax.

The y-coordinate $A_y$ of A in TikZ's internal coordinate system of the corresponding tikzpicture is:  \Ay.

This means: In order to find A in the tikzpicture you need to go from the origin
\Ax pt $\approx$ \pgfmathparse{StandardizeToUnit(\Ax,1cm)}\pgfmathresult cm{} in x-direction and
\Ay pt $\approx$ \pgfmathparse{StandardizeToUnit(\Ay,1cm)}\pgfmathresult cm{} in y-direction.

\bigskip

C was specified as: \verb|\coordinate (C) at (2,2);|

This means:

In order to determine the coordinates of C in the tikzpicture add two times TikZ's x-vector and two times TikZ's y-vector to the origin.\\
(At the time of specifying C/determining the coordinates of C in TikZ's internal coordinate system
\begin{itemize}
\item the x-vector was specified to point as many pt in x-direction as correspond to 1cm and to point 0pt in y-direction.
\item the y-vector was specified to point as many pt in y-direction as correspond to 1cm and to point 0pt in x-direction.
\end{itemize}%
The x-vector and the y-vector and the z-vector can be adjusted via \verb|\pgfsetxvec| respective \verb|\pgfsetyvec| respective \verb|\pgfsetzvec|.)

\bigskip

The x-coordinate $C_x$ of C in TikZ's internal coordinate system of the corresponding tikzpicture is:  \Cx.

The y-coordinate $C_y$ of C in TikZ's internal coordinate system of the corresponding tikzpicture is:  \Cy.

This means: In order to find C in the tikzpicture  you need to go from the origin
\Cx pt $\approx$ \pgfmathparse{StandardizeToUnit(\Cx,1cm)}\pgfmathresult cm{} in x-direction and
\Cy pt $\approx$ \pgfmathparse{StandardizeToUnit(\Cy,1cm)}\pgfmathresult cm{} in y-direction.

\bigskip

According to pythagoras in the tikzpicture the distance between A and C is
$\sqrt{(C_x-A_x)^2+(C_y-A_y)^2}$ $\approx$
\pgfmathparse{sqrt((\Cx-\Ax)*(\Cx-\Ax)+(\Cy-\Ay)*(\Cy-\Ay))}\pgfmathresult pt
$\approx$
\pgfmathparse{StandardizeToUnit(\pgfmathresult,1cm)}\pgfmathresult cm{}.

\end{document}