TransWikia.com

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

TeX - LaTeX Asked on December 27, 2020

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} 


newcommandDeclareConstant[2]{%
  pgfkeys{/MyStuff/declare constant={#1}{#2}}%
}%
newcommandDeclareConstants[1]{pgfkeys{/MyStuff/.cd,#1,}}%
newcommandexchangeargs[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@firstoftwoelseexpandafter@secondoftwofi
  {%
    GenericError{spacespace@spaces@spaces@spaces@spaces@spaces@spaces@spaces}%
                 {Constant declaration error: Name of constant not specified}%
                 {spacespace@spaces@spaces@spaces@spaces@spaces@spaces@spaces You cannot declare a constant withoutMessageBreak specifying its name.}%
                 {You need some sort of identifier for referencing the constant.}%
    ifcat$detokenizeexpandafter{pgfmathresult}$expandafter@firstofoneelseexpandafter@gobblefi
    {%
      GenericError{spacespace@spaces@spaces@spaces@spaces@spaces@spaces@spaces}%
                   {Constant declaration error: Value of constant not specified}%
                   {spacespace@spaces@spaces@spaces@spaces@spaces@spaces@spaces You cannot declare a constant withoutMessageBreak specifying its value.}%
                   {Which aspect of a constant could be constant if not its value?MessageBreak So there must be a value!}%
    }%
    endgroup
  }{%
    ifcat$detokenizeexpandafter{pgfmathresult}$expandafter@firstoftwoelseexpandafter@secondoftwofi
    {%
      GenericError{spacespace@spaces@spaces@spaces@spaces@spaces@spaces@spaces}%
                   {Constant declaration error: Value of constant not specified}%
                   {spacespace@spaces@spaces@spaces@spaces@spaces@spaces@spaces You cannot declare a constant withoutMessageBreak specifying its value.}%
                   {Which aspect of a constant could be constant if not its value?MessageBreak So there must be a value!}%
      endgroup
    }{%
      expandafterendgroup
      expandafterexchangeargsexpandafter{expandafter{%
        expandafterdef
        expandafterpgfmathresult
        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=...,
  % ...
};


defxa{1}
defya{1}
defxb{2}
defyb{2}
%
pgfmathsetmacro{xnewResults}{{add(multiply(sqrt(add(pow(subtract(xb,xa),2),pow(subtract(yb,ya),2))),cos(105)),1) }}
pgfmathsetmacro{ynewResults}{{add(multiply(sqrt(add(pow(subtract(xb,xa),2),pow(subtract(yb,ya),2))),sin(105)),1) }}
begin{equation*}
c=
begin{cases}
x_c=xnewResults 

y_c=ynewResults 
end{cases}
end{equation*}
%
defnum{.5}
defxa{1}
defya{1}
defxb{0.63397}
defyb{2.36603}
%
pgfmathsetmacro{xpointResults}{{add(multiply(subtract(1,num),xa),multiply(num,xb)) }}
pgfmathsetmacro{ypointResults}{{add(multiply(subtract(1,num),ya),multiply(num,yb)) }}
begin{equation*}
P_{Ac}=
begin{cases}
x_p=xpointResults 

y_p=ypointResults 
end{cases}
end{equation*}
end{document}


One Answer

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}
showpgfmathresult % 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))}
showpgfmathresult % 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}
%===================[adjust margins/layout for the example]====================
csname @ifundefinedendcsname{pagewidth}{}{pagewidth=paperwidth}%
csname @ifundefinedendcsname{pdfpagewidth}{}{pdfpagewidth=paperwidth}%
csname @ifundefinedendcsname{pageheight}{}{pageheight=paperheight}%
csname @ifundefinedendcsname{pdfpageheight}{}{pdfpageheight=paperheight}%
textwidth=paperwidth
oddsidemargin=2.5cm
marginparsep=.2oddsidemargin
marginparwidth=oddsidemargin
advancemarginparwidth-2marginparsep
advancetextwidth-2oddsidemargin
advanceoddsidemargin-1in
evensidemargin=oddsidemargin
textheight=paperheight
topmargin=2.5cm
footskip=.5topmargin
{normalfontglobaladvancefootskip.5htstrutbox}%
advancetextheight-2topmargin
advancetopmargin-1in
headheight=0ex
headsep=0ex
pagestyle{plain}
parindent=0ex
parskip=0ex 
topsep=0ex
partopsep=0ex
%==================[eof margin-adjustments]====================================

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

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-.5exhbox{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")}
globalletAx=pgfmathresult
pgfmathparse{YCoordinate("A")}
globalletAy=pgfmathresult
pgfmathparse{XCoordinate("C")}
globalletCx=pgfmathresult
pgfmathparse{YCoordinate("C")}
globalletCy=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}

enter image description here

Correct answer by Ulrich Diez on December 27, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP