定点算术:为什么 fp 有时能工作,但有时却会出错?

定点算术:为什么 fp 有时能工作,但有时却会出错?

为什么fixed point arithmetic喜欢在不进行任何数学运算的代码部分上出错?

我正在使用该包来改进我已经打印出来的一些角度的计算,但它正在评估一个仅仅是数字的节点并返回一个错误:

ERROR: FP error: Illegal character \c@pgf@counta  found in float number!.

--- TeX said ---
\FP@errmessage #1->\errmessage {FP error: #1!}

l.13   {};

--- HELP ---
From the .log file...

This error message was generated by an \errmessage
command, so I can't give any explicit help.
Pretend that you're Hercule Poirot: Examine all clues,
and deduce the truth by order and method.

\documentclass[convert = false, tikz]{standalone}
\usepackage{fp}
\usetikzlibrary{fixedpointarithmetic}
\begin{document}
\begin{tikzpicture}[fixed point arithmetic]
  \node[label = x] {};
\end{tikzpicture}
\end{document}

从上面的代码中,我们可以看出fp这个节点有问题。如果我删除fp,就不会有问题,但我希望稍后在实际计算的代码中使用该包。

答案1

发生了什么?

当 TikZ 处理 时,label它需要在标记节点的边界上找到适当的点。 的方向left将锚点设置为 的角度180。在此过程的后面,宏\pgf@sh@reanchor用于查找边界上此点的实际坐标。

此宏首先检查 是否180是此形状的命名锚点(如north westbase),如果不是,则检查锚点是否为通用锚点。如果它甚至不是通用锚点,则它只能是边界上的角点。180然后由 进行评估\pgfmathsetcounter)。结果存储在计数寄存器中\c@pgf@counta(即 LaTeX 计数器pgf@counta)。

\c@pgf@counta然后直接在 上使用\pgfqpointpolarq表示宏的“快速”版本\pgfpointplar,它(q即快速版本)不解析其参数,而是直接将它们发送到三角函数。通常,这种解析和评估由 PGF 数学完成,它会自动检测寄存器(如计数/计数器、尺寸和长度/跳过)并正确将它们扩展为它们的值(剥离任何单位)。

但是该fixedpointarithmetic库及其选项直接将这些三角函数映射到它们的fp对应部分。fp不容忍寄存器。

有错误?

我认为这是定义中的一个错误,\pgf@sh@reanchor因为似乎\pgfqpointpolarPGF 的所有其他用法都直接使用数字或扩展为数字的内容。

如何修复?

A简单修复使用etoolbox包装是:

\usepackage{etoolbox}
% You should have loaded tikz before this line!
\patchcmd\pgf@sh@reanchor{\c@pgf@counta}{\the\c@pgf@counta}{}{}

这也修复了角度锚点的直接使用,如(与您的示例保持一致):

\node at (P.90) {}; % or
\node[anchor=270] {};

west代替left

对于圆形未旋转节点,您实际上可以毫无问题地使用指南针锚点,因为它们直接映射到方向。因此,left您可以使用west。这将触发命名锚点并避免\pgfqpointpolar

这通常不适用于其他形状,至少对于对角线方向不起作用,如第二张 TikZ 图片所示。

或者您不使用它fixed point arithmetic作为标签。

当然,对于这个小任务来说,fp包和它的精度是不需要的,所以如果你可以避免它,fixed point arithmetic只在你真正需要它的路径上使用,比如说

\path[fixed point arithmetic] let <fancy calculations> in …;

如果需要,您可以构建一个到该长选项的快捷方式,例如:

\tikzset{fp/.style={fixed point arithmetic={#1}},fp/.default=}

代码

\documentclass[convert = false, tikz]{standalone}
\usepackage{fp}
\usetikzlibrary{fixedpointarithmetic}
\usepackage{etoolbox}
\makeatletter
\patchcmd\pgf@sh@reanchor{\c@pgf@counta}{\the\c@pgf@counta}{}{}
\makeatother
\begin{document}
\begin{tikzpicture}[fixed point arithmetic,
  every label/.append style = {font = \scriptsize},
  dot/.style = {inner sep = +0pt, shape = circle,
    draw = black, label = {#1}},
  small dot/.style = {minimum size = .05cm, dot = {#1}},
  big dot/.style = {minimum size = .1cm, dot = {#1}},
  ]
  \node[font = \scriptsize, small dot = {left: \(1\)}] (P) at (203.16381:3cm)
  {};
\end{tikzpicture}

\begin{tikzpicture}
  \node[fill,minimum width=1cm,label = {[red]north west:nw}, label = {[green]above left:al}, label=north:n] (a){};
  \foreach \sty/\an in {white/north, green/135, red/north west}\path[draw=\sty,fill=black] (a.\an) circle [radius=.8pt];
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

在此处输入图片描述

答案2

TikZ 使用\counter=\length技巧将长度(以 pt 为单位)乘以 65536 来获得整数sp单位数(egreg 教给我的)。因此,您经常可以看到临时 TikZ 计数器出现在计算中。\c@[email protected]

这里可能(我没有耐心等待结果\tracingall),极坐标计算涉及三角计算,当fp接管数学运算时,它无法处理它。相反,您可以使用fpuTikZ 本身的库,虽然使用起来有点繁琐,但它是本地常驻库。

以下是关于余弦运算如何停止的长代码片段的摘录。

\FPmul #1#2#3->\FP@callc \FP@mul #1{#2}{#3}
#1<-\pgfmathresult 
#2<-\c@pgf@counta 
#3<-0.017453292519943295

本来应该将#2和相乘#3并将其写入,#1但却#2违反了fp。这实际上可能是fixed point aritmetic库中的一个错误。

相关内容