下面的代码摘录自:
(代码 exam1b-本例中的第二个编码集)
和
有没有办法结合使用这两个宏来
能够提取线长度并将其分配给变量,以便我以后可以使用该变量作为其他操作的输入?
将提取的线长度设置为厘米、英寸……或任何需要的单位
能够提取点坐标并将它们分配给变量,以便我以后可以使用该变量作为其他操作的输入?
这是 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}
%
\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*}
%
\def\num{.5}
\def\xa{1}
\def\ya{1}
\def\xb{0.63397}
\def\yb{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}
答案1
根据矢量计算规则可以计算出两点之间的距离。
TikZ 的问题是:
TikZ 是一种在纸上绘画的手段。
更摘要:
TikZ 用于通过二维平面可视化/描绘任何事实。
为此,TikZ 内部为每个 tikzpicture 使用一个由二维笛卡尔坐标系跨越的平面,其基向量彼此垂直且长度为 1pt。(根据 TeXbook,第 10 章:72.27pt = 2.54cm <-> (72.27/2.54)pt = 1cm)
所有位置数据/所有坐标均通过用户输入提供,例如\coordinate (AB) at (1.25,0.25);
都是内部的立即地由 TikZ 转换至其内部坐标系。
即使您想要使用 x、y 和 z 坐标显示三维物体,三维坐标也会立即转换为内部用于绘制描绘的二维坐标。
所有内容立即转换的情况意味着 TikZ 本身仅保存与要创建的图像/图片相关的数据。TikZ
不会保存与图像所表示的数据本身相关的数据。
例如,通过 TikZ 本身保存的数据,您可以得出描绘的组成部分一条线的长度。
但是从 TikZ 本身存储的数据中,我们只能得出非常有限的数据,例如属于要描述的事实本身的物理值或其他量的值。
例如,如果您使用 TikZ 绘制三维金字塔,则可以使用 TikZ 本身保存的数据来计算描绘中的线有多长,该线在描绘中代表金字塔的高度。这指的是描绘。无法使用这些数据计算三维金字塔本身的高度。这是因为 TikZ 提供的数据指的是描绘,即二维的东西,而金字塔是三维物体。在 TikZ 本身的数据库存中,缺少有关要描绘的物体的三维性的信息。
以 TikZ 包本身保存的数据为基础进行计算(参考要表示的事实)在我看来是错误的方法。
相反,指定您想要描绘的所有数量以及其值要在描绘中显示。
当指定这些数量时,您当然可以使用\pgfmathparse
来计算。但是,请注意,\pgfmathparse
计算方式通常会产生较小的舍入误差/转换误差。
例如,如果你将长度 1.5cm 放入\pgfmathparse
—即\pgfmathparse{1.5cm}
,结果这个数量的数值将存储在 中的宏中\pgfmathresult
,标准化为单位1pt
。如果你想将这个数量的数值标准化为单位 1cm ,因此执行\pgfmathparse{scalar((\pgfmathresult)*(1pt/1cm))}
,那么结果将不是 ,1.5
而是类似于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
如果您打算使用 TikZ 在 tikzpicture 本身范围内保存的数据进行计算以执行与描述相关的操作,您可以获取 xy 坐标(标准化为 1pt 的坐标数值),例如,通过执行以下操作:
您需要牢记,不应被理解为\pgfmathparse
数学运算符或数学函数名称的事物(例如“坐标”名称)必须放在"
在 的参数中出现时\pgfmathparse
/在由 处理的事物中出现时之间\pgfmathparse
。
顺便说一句,我认为在 TikZ\coordinate
中作曲x 和 y(以及 z)值的表示非常奇怪。在常见用法中,例如 x 值本身就是坐标,而不是坐标的组成部分。
\documentclass{article}
\usepackage{stanli}
%===================[adjust margins/layout for the example]====================
\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
\advance\marginparwidth-2\marginparsep
\advance\textwidth-2\oddsidemargin
\advance\oddsidemargin-1in
\evensidemargin=\oddsidemargin
\textheight=\paperheight
\topmargin=2.5cm
\footskip=.5\topmargin
{\normalfont\global\advance\footskip.5\ht\strutbox}%
\advance\textheight-2\topmargin
\advance\topmargin-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)))}%
\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}