定点算术现在都很古怪

定点算术现在都很古怪

在此之前Tikz 3.0,使用\usepackage{fp}\usetikzlibrary{fixedpointarithmetic}会增加计算的准确性。

自从更新以来,我还没有用过这些包。不过,今天我试用了一下,结果很糟糕。

为什么fixed point arithmetic affecting我的盒子的质量为 M,且 3 条边的弧度都低估了?

另外,盒子的向量取决于盒子的位置。当盒子移动时,向量怎么能保持不变呢?

我用fixed point arithmetic它来计算\draw let语法中的角度。

  \draw[-stealth, fixed point arithmetic] let
    \p0 = (O),
    \p1 = (P1),
    \p2 = (P2),
    \n1 = {atan2(\y1 - \y0, \x1 - \x0)},
    \n2 = {atan2(\y2 - \y0, \x2 - \x0)},
    \n3 = {1cm},
    \n4 = {(\n1 + \n2)/2}
  in \pgfextra{\xdef\myn{\n2}} (O) +(\n1:\n3) arc[radius = \n3,
  start angle = \n1, end angle = \n2] node[right, font = \tiny] at (\n4:\n3)
  {$\theta$};

如果没有fixed point arithmetic,图像将是:

在此处输入图片描述

和:

在此处输入图片描述

代码:

\documentclass[tikz, convert = false]{standalone}%

\usepackage{fp}
\usetikzlibrary{fixedpointarithmetic}
\usetikzlibrary{calc}
\usetikzlibrary{intersections}
\usetikzlibrary{backgrounds}

\begin{document}
\begin{tikzpicture}[line join = round, line cap = round]
  \coordinate (O) at (0, 0);

  \draw (O) -- +(3, 0) coordinate (P1);
  \draw[name path = sline] (O) -- (3, 2) coordinate (P2);

  \draw[-stealth, fixed point arithmetic] let % remove fpa for it work
    \p0 = (O),
    \p1 = (P1),
    \p2 = (P2),
    \n1 = {atan2(\y1 - \y0, \x1 - \x0)},
    \n2 = {atan2(\y2 - \y0, \x2 - \x0)},
    \n3 = {1cm},
    \n4 = {(\n1 + \n2)/2}
  in \pgfextra{\xdef\myn{\n2}} (O) +(\n1:\n3) arc[radius = \n3,
  start angle = \n1, end angle = \n2] node[right, font = \tiny] at (\n4:\n3)
  {$\theta$};

  \path[name path = line1] (1.5, 0) -- +(0, 1.25);
  \path[name path = line2] (2, 0) -- +(0, 1.5);
  \path[name intersections = {of = sline and line1, by = P3}];
  \path[name intersections = {of = sline and line2, by = P4}];

  \draw (P3) -- ($(P3)!.25cm!-90:(O)$) coordinate (P5);
  \draw (P4) -- ($(P4)!.25cm!-90:(O)$) coordinate (P6);
  \draw[name path = boxtop] (P5) -- (P6) node[pos = .5, below, font = \tiny,
  rotate = \myn] {$M$};

  \path[name path = grav] ($(P5)!.75!(P6)$) -- +(0, -1.25);
  \path[name intersections = {of = grav and sline, by = P7}];

  \begin{scope}[on background layer]
    \draw[-latex, blue] (P7) -- ($(P7)!.75cm!-270:(O)$) coordinate (P8)
    node[pos = 1.25, font = \tiny, color = black] {$F_2$};

    \path[name path = perl1] (P8) -- ($(P8)!.75cm!-270:(P7)$);
    \path[name intersections = {of = perl1 and grav, by = P9}];

    \draw[-latex, blue] (P7) -- (P9) node[below, font = \tiny, inner sep = .3,
    color = black] {$Mg$};
    \draw[blue] (P9) -- (P8);

    \path[name path = norm] (P7) -- ($(P7)!.75cm!-90:(O)$);
    \path[name intersections = {of = norm and boxtop, by = P10}];

    \draw[-latex,blue] (P10) -- ($(P10)!.5cm!-90:(P5)$) node[pos = 1.15,
    font = \tiny, rotate = {\myn}, color = black] {$N$};

    \coordinate (P11) at ($(P3)!.5!(P5)$);
    \coordinate (P12) at ($(P4)!.5!(P6)$);

    \draw[-latex, blue] (P12) -- ++(\myn:.5) node[pos = 1.25, font = \tiny,
    rotate = {\myn}, color = black] {$F_f$};
    \draw[-latex, blue] (P11) -- ++({\myn + 180}:.5) node[pos = 1.25,
    font = \tiny, rotate = {\myn}, color = black] {$F_1$};
  \end{scope}
\end{tikzpicture}
\end{document}

答案1

pgflibraryfixedpointarithmetic.code.tex这是宏定义中行尾的空格导致的一个错误(使用 TikZ 3.0 测试;文件大小 13595 字节) \pgfmathfpabs@

\def\pgfmathfpabs@#1{%
        \begingroup%
                \FPabs\pgfmathresult{#1}
        \pgfmath@smuggleone\pgfmathresult%
        \endgroup%
}

空格在第三行之后。更正后的版本:

\def\pgfmathfpabs@#1{%
        \begingroup%
                \FPabs\pgfmathresult{#1}%
        \pgfmath@smuggleone\pgfmathresult%
        \endgroup%
}

代码中atan2使用了两次函数abs。插入的空格导致后面的元素向右移动;原点不再位于 (0,0),而是向右移动。

\pgfmathfpsec@和的定义也\pgfmathfpcosec存在同样的问题。

解决方法:

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

梅威瑟:

\documentclass[tikz, convert = false]{standalone}%

\usepackage{fp}
\usetikzlibrary{fixedpointarithmetic}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}

  \fill[blue] (0,0) circle[radius=1pt];
  \fill(1,0) circle[radius=.5pt];

  \path[
    fixed point arithmetic
  ] let
    \n1 = {atan2(57pt, 85pt)}
  in;

  \fill[red] (0,0) circle[radius=.5pt];

\end{tikzpicture}
\end{document}

未修复:

无修复

修复后:

固定的

答案2

仅使用范围来计算atan2对我来说是可行的。这个范围似乎是必要的,但我不知道为什么。

\documentclass[tikz, convert = false]{standalone}%

\usepackage{fp}
\usetikzlibrary{fixedpointarithmetic}
\usetikzlibrary{calc}
\usetikzlibrary{intersections}
\usetikzlibrary{backgrounds}

\begin{document}
\begin{tikzpicture}[line join = round, line cap = round]
  \coordinate (O) at (0, 0);

  \draw (O) -- +(3, 0) coordinate (P1);
  \draw[name path = sline] (O) -- (3, 2) coordinate (P2);

  \begin{scope}
    \path[fixed point arithmetic] let 
      \p0 = (O),
      \p1 = (P1),
      \p2 = (P2),
      \n1 = {atan2(\y1 - \y0, \x1 - \x0)},
      \n2 = {atan2(\y2 - \y0, \x2 - \x0)}
    in \pgfextra{\xdef\mym{\n1}\xdef\myn{\n2}}; 
  \end{scope}

  \draw[-stealth] let
    \n3 = {1cm},
    \n4 = {(\mym + \myn)/2} in
    (O) +(\mym:\n3) arc[radius = \n3,
  start angle = \mym, end angle = \myn] node[right, font = \tiny] at (\n4:\n3)
  {$\theta$};

  \path[name path = line1] (1.5, 0) -- +(0, 1.25);
  \path[name path = line2] (2, 0) -- +(0, 1.5);
  \path[name intersections = {of = sline and line1, by = P3}];
  \path[name intersections = {of = sline and line2, by = P4}];

  \draw (P3) -- ($(P3)!.25cm!-90:(O)$) coordinate (P5);
  \draw (P4) -- ($(P4)!.25cm!-90:(O)$) coordinate (P6);
  \draw[name path = boxtop] (P5) -- (P6) node[pos = .5, below, font = \tiny,
  rotate = \myn] {$M$};

  \path[name path = grav] ($(P5)!.75!(P6)$) -- +(0, -1.25);
  \path[name intersections = {of = grav and sline, by = P7}];

  \begin{scope}[on background layer]
    \draw[-latex, blue] (P7) -- ($(P7)!.75cm!-270:(O)$) coordinate (P8)
    node[pos = 1.25, font = \tiny, color = black] {$F_2$};

    \path[name path = perl1] (P8) -- ($(P8)!.75cm!-270:(P7)$);
    \path[name intersections = {of = perl1 and grav, by = P9}];

    \draw[-latex, blue] (P7) -- (P9) node[below, font = \tiny, inner sep = .3,
    color = black] {$Mg$};
    \draw[blue] (P9) -- (P8);

    \path[name path = norm] (P7) -- ($(P7)!.75cm!-90:(O)$);
    \path[name intersections = {of = norm and boxtop, by = P10}];

    \draw[-latex,blue] (P10) -- ($(P10)!.5cm!-90:(P5)$) node[pos = 1.15,
    font = \tiny, rotate = {\myn}, color = black] {$N$};

    \coordinate (P11) at ($(P3)!.5!(P5)$);
    \coordinate (P12) at ($(P4)!.5!(P6)$);

    \draw[-latex, blue] (P12) -- ++(\myn:.5) node[pos = 1.25, font = \tiny,
    rotate = {\myn}, color = black] {$F_f$};
    \draw[-latex, blue] (P11) -- ++({\myn + 180}:.5) node[pos = 1.25,
    font = \tiny, rotate = {\myn}, color = black] {$F_1$};
  \end{scope}
\end{tikzpicture}
\end{document}

在此处输入图片描述

在这个例子中,fixed point arithmetic选项也可以是范围或图片的参数,但在每种情况下我都必须使用这个额外的范围来计算 atan2。

\begin{tikzpicture}[line join = round, line cap = round,
  fixed point arithmetic
]
...
  \begin{scope}
    \path let 
      \p0 = (O),
      \p1 = (P1),
      \p2 = (P2),
      \n1 = {atan2(\y1 - \y0, \x1 - \x0)},
      \n2 = {atan2(\y2 - \y0, \x2 - \x0)}
    in \pgfextra{\xdef\mym{\n1}\xdef\myn{\n2}}; 
  \end{scope}

  \draw[-stealth] let
    \n3 = {1cm},
    \n4 = {(\mym + \myn)/2} in
    (O) +(\mym:\n3) arc[radius = \n3,
  start angle = \mym, end angle = \myn] node[right, font = \tiny] at (\n4:\n3)
  {$\theta$};
...

结果和上面一样。

答案3

这不是答案,但我认为你不需要fp。使用 PGF 本身,结果也相当准确。

\documentclass[tikz]{standalone}
\usetikzlibrary{angles,quotes,calc}
\begin{document}
\begin{tikzpicture}
% Angle label
\draw (0,0) coordinate (O) -- +(3, 0) coordinate (P1) (O)-- +(3, 2) coordinate (P2)
pic ["$\theta$",draw,->,angle eccentricity=1.2,angle radius=1cm] {angle = P1--O--P2};
% Angle value
\path let \p1=($(P2)-(O)$),\n1={atan2(\y1,\x1)} in \pgfextra{\xdef\myn{\n1}};
% Mass placement
\node[minimum width=1cm,draw,anchor=south,rotate=\myn] (m) at ($(O)!0.7!(P2)$) {M};
% Ortho-Forces
\foreach \x[count=\xi from 0] in {F_f,N,F_1,F_2}{
\draw[-latex,draw=blue] (m.\xi*90) --++(\xi*90+\myn:5mm) 
node[,inner sep=2pt,anchor=90*(\xi+3),font=\tiny] {$\x$};
}
% Gravity
\draw[-latex,draw=blue] (m.south) --++(0,{-1/cos(\myn)*5mm}) node[font=\tiny,left] (mg) {$mg$};
% Tangential component
\draw[blue] (mg.east) -- ++(\myn:{tan(\myn)*5mm});
\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容