某些特殊坐标的圆弧无法正确绘制

某些特殊坐标的圆弧无法正确绘制

在尝试在 TikZ 中绘制一些几何图形时,我在绘制圆弧来标记角度时遇到了问题。圆弧总是太短,不会与角度的两条射线相交。(这不是 PDF 缩放问题,圆弧在所有缩放级别下都会变短)。我还注意到,稍微扰动其中一个坐标可以修复圆弧。以下是一些代码和输出,显示了我的意思:

\documentclass[draft]{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

% A = (-4,1.999)
\begin{tikzpicture}
    \coordinate [label=below:{$B$}] (B) at (-6,0);
    \coordinate [label=below:{$C$}] (C) at (0,0);
    \coordinate [label=above:{$A$}] (A) at (-4,1.999);

    \draw let \p1=($(B)$),\p2=($(A)$) in
        (-1,0) arc (atan2(\x1,\y1):atan2(\x2,\y2):1);

    \draw (B) -- (C) -- (A);
\end{tikzpicture}

% A = (-4,2)
\begin{tikzpicture}
    \coordinate [label=below:{$B$}] (B) at (-6,0);
    \coordinate [label=below:{$C$}] (C) at (0,0);
    \coordinate [label=above:{$A$}] (A) at (-4,2.0);

    \draw let \p1=($(B)$),\p2=($(A)$) in
        (-1,0) arc (atan2(\x1,\y1):atan2(\x2,\y2):1);

    \draw (B) -- (C) -- (A);
\end{tikzpicture}

% A = (-4,2.001)
\begin{tikzpicture}
    \coordinate [label=below:{$B$}] (B) at (-6,0);
    \coordinate [label=below:{$C$}] (C) at (0,0);
    \coordinate [label=above:{$A$}] (A) at (-4,2.001);

    \draw let \p1=($(B)$),\p2=($(A)$) in
        (-1,0) arc (atan2(\x1,\y1):atan2(\x2,\y2):1);

    \draw (B) -- (C) -- (A);
\end{tikzpicture}
\end{document}

在此处输入图片描述

我想知道为什么这种情况只发生在 A=(-4,2) 时。也许我误用了 atan2?

答案1

您的使用没有问题,但 TikZ 的开发人员更新了数学库的 CVS 版本。罪魁祸首似乎是除法算法,所以如果我将 CVS 版本的相关部分复制到稳定版本 (v2.10) 中,它就会按预期工作。

由于只需很小的扰动即可解决问题,因此下面的代码仅用于演示目的。

\documentclass[draft]{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\makeatletter

\def\pgfmathdivide@@{%
    \let\pgfmath@next=\relax%
    \ifdim\pgfmath@small@number pt<\pgfmath@x%
        \ifdim\pgfmath@small@number pt<\pgfmath@y%
            \ifdim\pgfmath@y>\pgfmath@x%
                \ifpgfmath@divide@period%
                    \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult.}%
                    \pgfmath@divide@periodfalse%
                \fi%
                \pgfmathdivide@dimenbyten\pgfmath@y%
                \ifdim\pgfmath@y>\pgfmath@x%
                    \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmathresult0}%
                \fi%
            \else%
                \c@pgfmath@counta=\pgfmath@x%
                \c@pgfmath@countb=\pgfmath@y%
                \divide\c@pgfmath@counta by\c@pgfmath@countb%
                \pgfmath@ya=\c@pgfmath@counta\pgfmath@y%
                \advance\pgfmath@x by-\pgfmath@ya%
                \def\pgfmath@next{%
                    \toks0=\expandafter{\pgfmathresult}%
                    \edef\pgfmathresult{\the\toks0 \the\c@pgfmath@counta}%
                }%
                \ifpgfmath@divide@period
                \else
                            \ifnum\c@pgfmath@counta>9 %
                        \expandafter\pgfmathdivide@advance@last@digit\pgfmathresult CCCCC\@@
                        \advance\c@pgfmath@counta by-10 %
                        \ifnum\c@pgfmath@counta=0
                            \let\pgfmath@next=\relax
                        \fi
                    \fi
                \fi
                \pgfmath@next
            \fi%
            \let\pgfmath@next=\pgfmathdivide@@%
        \fi%
    \fi%
    \pgfmath@next%
}

% advances the last digit found in the number. Any missing digits are
% supposed to be filled with 'C'.
\def\pgfmathdivide@advance@last@digit#1.#2#3#4#5#6#7\@@{%
    \pgfmath@ya=\pgfmathresult pt %
    \if#2C%
        \pgfmath@xa=1pt %
    \else
        \if#3C%
            \pgfmath@xa=0.1pt %
        \else
            \if#4C%
                \pgfmath@xa=0.01pt %
            \else
                \if#5C%
                    \pgfmath@xa=0.001pt %
                \else
                    \if#6C%
                        \pgfmath@xa=0.0001pt %
                    \else
                        \pgfmath@xa=0.00001pt %
                    \fi
                \fi
            \fi
        \fi
    \fi
    \advance\pgfmath@ya by\pgfmath@xa
    \edef\pgfmathresult{\pgfmath@tonumber@notrailingzero\pgfmath@ya}%
}%
{
\catcode`\p=12
\catcode`\t=12
\gdef\Pgf@geT@NO@TRAILING@ZERO#1.#2pt{%
    #1.%
    \ifnum#2=0 \else #2\fi
}
}
\def\pgfmath@tonumber@notrailingzero#1{\expandafter\Pgf@geT@NO@TRAILING@ZERO\the#1}


\makeatother
\begin{document}


\begin{tikzpicture}
\foreach \x[count=\xi] in {1.999,2.0,2.001}{
\coordinate (a\xi) at (-4,\x);
\node at (0,\xi) {\pgfmathparse{-4/\x}\pgfmathresult};
\node at (2,\xi) {\pgfmathparse{atan(-4/\x)}\pgfmathresult};
\node at (4,\xi) {\pgfmathparse{atan2(-4,\x)}\pgfmathresult};
}
\end{tikzpicture}

\begin{tikzpicture}
    \coordinate [label=below:{$B$}] (B) at (-6,0);
    \coordinate [label=below:{$C$}] (C) at (0,0);
    \coordinate [label=above:{$A$}] (A) at (-4,1.999);

    \draw let \p1=($(B)$),\p2=($(A)$) in
        (-1,0) arc (atan2(\x1,\y1):atan2(\x2,\y2):1);

    \draw (B) -- (C) -- (A);
\end{tikzpicture}

% A = (-4,2)
\begin{tikzpicture}
    \coordinate [label=below:{$B$}] (B) at (-6,0);
    \coordinate [label=below:{$C$}] (C) at (0,0);
    \coordinate [label=above:{$A$}] (A) at (-4,2.0);

    \draw let \p1=($(B)$),\p2=($(A)$) in
        (-1,0) arc (atan2(\x1,\y1):atan2(\x2,\y2):1);

    \draw (B) -- (C) -- (A);
\end{tikzpicture}

% A = (-4,2.001)
\begin{tikzpicture}
    \coordinate [label=below:{$B$}] (B) at (-6,0);
    \coordinate [label=below:{$C$}] (C) at (0,0);
    \coordinate [label=above:{$A$}] (A) at (-4,2.001);

    \draw let \p1=($(B)$),\p2=($(A)$) in
        (-1,0) arc (atan2(\x1,\y1):atan2(\x2,\y2):1);

    \draw (B) -- (C) -- (A);
\end{tikzpicture}
\end{document}

相关内容