为什么 samples 选项与 fp 冲突?

为什么 samples 选项与 fp 冲突?

最小工作示例:

\documentclass{amsart}
\usepackage{fp}
\usepackage{tikz}
\usetikzlibrary{fixedpointarithmetic}
\begin{document}
\begin{tikzpicture}[scale=2, fixed point arithmetic]
\draw[domain=0:360, samples=100] plot ({2*cos(\x)}, {sin(\x)});
\end{tikzpicture}
\end{document}

这会出现错误:!FP 错误:在浮点数中发现非法字符 100!。

如果我删除样本选项或定点算术选项,渲染时不会出错。我找不到任何文档来说明为什么会出现这种情况或如何避免此问题。

使用平滑选项而不进行手动样本控制会产生不充分的结果:不仅曲线看起来有点不平整,而且平滑在参数化的端点处完全失败。

如果将参数化的端点移动到曲率最低的点(通过将域更改为 90:450),则会取得一些成功,但仍然会有明显的锐度,而且这不会影响轻微的块状感。

将渲染分成两部分,使样本量加倍:

\draw[domain=90:270, smooth] plot ({2*cos(\x)}, {sin(\x)});
\draw[domain=270:450, smooth] plot ({2*cos(\x)}, {sin(\x)});

你得到了一个椭圆的两半,它们都比原始渲染更平滑,但令人费解的是,在远处彼此。

注意:我了解原生绘制椭圆功能。上面的示例是根据我的实际需求高度简化的。

编辑:使用在另一个问题中发现的错误修复:

替换

\usetikzlibrary{fixedpointarithmetic}

\endlinechar=-1
\usetikzlibrary{fixedpointarithmetic}
\endlinechar=13

椭圆一半位移的错误已得到纠正;结果是一个公平但并不理想的解决方案。其余问题仍然存在。

答案1

问题在于,fixedpointarithmetic假设需要两个参数。相反,像调用\pgfmathmax@这样的构造\pgfmathparse{max(1,2,3)}

\pgfmathmax@{{1}{2}{3}}

而它的职责就是\pgfmathmax@理清事情,找到最大值。

既然问题出现了samples=<value>max(2,<value>)

图书馆fixedpointarithmetic确实

\let\pgfmathmax@\pgfmathfpmax@

其中宏\pgfmathfpmax@定义有两个参数。因此每次\pgfmathmax@调用时,它都会多消耗一个标记。如果max只在两个数字之间计算,则可以轻松修复该错误,但如果 TikZ 程序需要max在两个以上的数量之间进行计算,它就会崩溃。

例如

\begin{tikzpicture}[fixed point arithmetic]
\pgfmathparse{max(2,100,123)};
\end{tikzpicture}

将导致存储100\pgfmathresult打印 123。

该函数的调用min将以同样的方式中断。

还有\pgfmathfpmax一个问题: 之后\pgrmathfpmax{1}{2},宏\pgfmathresult将扩展为\pgfmathresult,而不是2。 也是一样\pgfmathfpmin

对于特定问题的一个非常部分的修复是

\documentclass{amsart}
\usepackage{etoolbox}
\usepackage{fp}
\usepackage{tikz}

\usetikzlibrary{fixedpointarithmetic}

\makeatletter
% partial fix for the bug
\let\buggy@pgfmathfpmax@\pgfmathfpmax@
\def\pgfmathfpmax@#1{\buggy@pgfmathfpmax@#1}
% remove the bad \unskip tokens
\patchcmd\pgfmathfpscientific{\unskip}{}{}{}
\patchcmd{\pgfmathfppow@}{\unskip}{}{}{}
% remove the wrong space in \FP@pow
\patchcmd{\FP@pow}
  { }{}
  {\typeout{Fixed \string\FP@pow}}
  {\typeout{\noexpand\FP@pow needs no patch}}
\makeatother

\begin{document}

\begin{tikzpicture}[scale=2, fixed point arithmetic]
\draw[domain=0:360, samples=99] plot ({2*cos(\x)}, {sin(\x)});
\end{tikzpicture}
\end{document}

然而,这只能修复samples处理密钥时完成的特定调用。

fixedpointarithmetic我的建议是,在错误被修复之前,不要考虑这个库。

我还添加了几个安全修复程序,以避免空格蔓延,比使用加载库更好\endlinechar=-1

答案2

代码max拾取了尾随的\fi完整修复,以便准确追踪尚未正确删除的位置,但快速修复是对其进行测试并在最大值中处理它:

在此处输入图片描述

\documentclass{amsart}
\usepackage{fp}
\usepackage{tikz}
\endlinechar=-1
\usetikzlibrary{fixedpointarithmetic}
\endlinechar=13

\makeatletter
\def\pgf@fitest{\fi}

\def\pgfmathfpmax@#1#2{%
\def\pgf@tmp{#2}%
\ifx\pgf@tmp\pgf@fitest
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\pgf@fitest\pgfmathfpmax@#1}%
{\begingroup%
        \FPifgt{#1}{#2}%
            \def\pgfmathresult{#1}%
        \else%
            \def\pgfmathresult{#2}%
        \fi%
        \pgfmath@smuggleone\pgfmathresult%
    \endgroup%
}}
        \let\pgfmathmax@=\pgfmathfpmax@%

\begin{document}
\begin{tikzpicture}[scale=2, fixed point arithmetic]
\draw[domain=0:360, samples=100] plot ({2*cos(\x)}, {sin(\x)});
\end{tikzpicture}
\end{document}

相关内容