是否有一个聪明的解决方案来解决 atan 的精度问题?

是否有一个聪明的解决方案来解决 atan 的精度问题?
\documentclass[pstricks,border=12pt]{standalone}

\psset{unit=.25}
\def\Atom#1{%
\begin{pspicture}[dimen=m](-12,-12)(12,12)
    \pstVerb{/AA 1 5 atan def /RR 26 sqrt def}
    \pscustom[fillstyle=eofill,fillcolor=red,linearc=#1]
    {
            \pscircle{3}
            \moveto(5,-1)
            \psLoop{6}
            {
                    \translate(5,0)
                    \psline(0,-1)(4,-1)(4,1)(0,1)
                    \translate(-5,0)
                    \psarc(0,0){!RR}{!AA}{!60 AA sub}
                    \rotate{60}
            }
            \closepath
    }
\end{pspicture}}

\begin{document}
\Atom{.5}
\Atom{0}
\end{document}

是什么原因导致下面非零的奇怪输出linearc

输出linearc=.5

在此处输入图片描述

输出linearc=0

在此处输入图片描述

编辑

根据 Werner 的评论,这与精度问题有关。 有没有什么聪明的方法可以解决这个问题?

答案1

如果当前路径有一个点(\moveto,上一个\psarc),则\psline 还从当前点到其第一个坐标绘制一条线。理论上两个点是相同的。但是这些点的计算完全不同, 的终点\psarc和 的第一个点\psline旋转。因此在实践中无法避免舍入误差。结果是一条非常细的线,比要绘制的\rotate{60}圆弧小得多。linearc

解决方案:只需删除多余的点,即第一点\psline

\documentclass[pstricks,border=12pt]{standalone}

\psset{unit=.25}
\def\Atom#1{%
\begin{pspicture}[dimen=m](-12,-12)(12,12)
    \pstVerb{/AA 1 5 atan def /RR 26 sqrt def}
    \pscustom[fillstyle=eofill,fillcolor=red,linearc=#1]
    {
            \pscircle{3}
            \moveto(5,-1)
            \psLoop{6}
            {
                    \translate(5,0)
                    \psline(4,-1)(4,1)(0,1)
                    \translate(-5,0)
                    \psarc(0,0){!RR}{!AA}{!60 AA sub}
                    \rotate{60}
            }
            \closepath
    }
\end{pspicture}}

\begin{document}
\Atom{.5}
\end{document}

结果

答案2

不使用atan,只使用sin,甚至不使用三角学,小角度可达 12°(实际上 24°),没有差异,例如 15° 和一点间隙。绘图在一条路径中完成。

  1. 淡红色为精确溶液;
  2. 蓝色,无三角块。

对于 10°:

在此处输入图片描述

飞涨 :

在此处输入图片描述

对于 15°(小间隙):

在此处输入图片描述

\documentclass[tikz,margin=2pt]{standalone}
\usetikzlibrary{calc}
\begin{document}

\def\Rex{5}
\def\Rin{3}
\def\Theeth{2}
\def\Angle{10}
\def\R{.3}
\pgfmathsetmacro\Lt{2*sin(\Angle)*\Rex}
\pgfmathsetmacro\L{2*\Rex*\Angle*3.14159/180}

\begin{tikzpicture}

%\clip (-5,2) rectangle (0,7) ;

% exact solution
% with trigonometry but whithout atan, just a sin
% in red

\fill[fill=red!25,,even odd rule]  (-\Angle:\Rex)
\foreach \i in {0,60,...,300} {
    --(-\Angle+\i:\Rex)
    --++(\i:\Theeth-\R) arc (-90+\i:0+\i:\R)
    --++(90+\i:\Lt-2*\R) arc (0+\i:90+\i:\R)
    --(\Angle+\i:\Rex) arc (\Angle+\i:60-\Angle+\i:\Rex)
} -- cycle (0,0) circle (\Rin);

% approximative solution without trigonometry
% if x is small sin(x) ~ x in radian

\draw[blue] (0,0) circle (\Rin) (-\Angle:\Rex)
\foreach \i in {0,60,...,300} {
    --(-\Angle+\i:\Rex)
    --++(\i:\Theeth-\R) arc (-90+\i:0+\i:\R)
    --++(90+\i:\L-2*\R) arc (0+\i:90+\i:\R)
    --(\Angle+\i:\Rex) arc (\Angle+\i:60-\Angle+\i:\Rex)
} -- cycle ;

\end{tikzpicture}
\end{document}

相关内容