通过指定端点和距离而不是角度和半径在 TikZ 中绘制圆圈

通过指定端点和距离而不是角度和半径在 TikZ 中绘制圆圈

在 TikZ 中的经典arc命令中,我们指定圆弧的端点,然后是初始角和最终角,最后是半径。

我想创建一个宏(如果它尚不存在),它不指定角度和半径,而是指定两个距离,一个水平,一个垂直,如下所示:

在此处输入图片描述

请注意,此命令的功能不如通常的命令强大,arc因为它仅绘制关于某个垂直轴对称的圆弧。转换公式如下:半径为 $\frac{a^2+b^2}{2b}$,初始角度为 $cos^{-1}(\frac{2ab}{a^2+b^2})$。

这是我实现这一点的失败尝试tikzset(在下面的测试文件中,两个 tikzpictures 应该相同):

\documentclass{article}
\usepackage{tikz}
\usepackage{calc}

\begin{document}

\tikzset{
    afro/.style args={#1:#2}{
        insert path={ arc(acos((2*#1*#2)/(#1*#1+#2*#2)):180-acos((2*#1*#2)/(#1*#1+#2*#2)):((#1*#1+#2*#2)/(2*#1*#2)))}
    }
}


\begin{tikzpicture}
\draw[green] (0,0) arc (37:143:2.5cm);
\draw (0,0) node {$O$};
\end{tikzpicture}

\begin{tikzpicture}
\draw[red] (0,0) afro (2cm:1cm);
\draw (0,0) node {$O$};
\end{tikzpicture}


\end{document}

也许我应该使用 pgfkeys?任何帮助都值得感激。

答案1

这里有一些想法。

测试可以在操作(使用)\ifpgfmathunitsdeclared之后进行。当在数学评估中的任何地方使用具有维度的东西(TeX dimen 或简单的语句,如 )时,测试将为真。如果在(a) 或(b)中使用了单位,则假定您想在画布坐标系中绘制圆弧,否则在本地坐标系中绘制圆弧。(参见vs )\pgfmathparse\pgfmathsetmacro2cm#1#2(1, 2)(1cm, 2cm)

由于使用了两次,因此之前也进行了角度的计算。

/utils/exec密钥没有什么特殊作用,它只是执行给定的代码(\pgfextra基本上)。


请注意,arc (…)路径运算符已被弃用。最好使用路径arc […]运算符,这样您可以在外部作用域中声明各种选项或在样式中使用它every arc


arc[a=2, b=1]如果您想使用没有辅助样式的东西,则需要更多的魔法chord do

代码

\documentclass[tikz]{standalone}
\tikzset{
  chord/.style args={#1:#2}{
    /utils/exec=%
      \pgfmathsetmacro\myTempVal{(#1)*(#1)/(#2)/2+(#2)/2}%
      \ifpgfmathunitsdeclared\edef\myTempVal{\myTempVal pt}\fi
      \pgfmathsetmacro\myTempAng{acos(2*(#1)*(#2)/((#1)*(#1)+(#2)*(#2)))},
    radius=\myTempVal, start angle=\myTempAng, end angle=180-\myTempAng},
  afro/.style={insert path={arc[chord={#1}]}},
  chord a/.initial=, chord b/.initial=,
  chord do/.style={chord={\pgfkeysvalueof{/tikz/chord a}:\pgfkeysvalueof{/tikz/chord b}}},
}

\begin{document}
\begin{tikzpicture}
\draw[green] (0,0) arc (37:143:2.5cm);
\draw (0,0) node {$O$};
\end{tikzpicture}

\begin{tikzpicture}
\draw[red] (0,0) [afro=2cm:1cm];
\draw (0,0) node {$O$};
\end{tikzpicture}

\begin{tikzpicture}
\draw[blue] (0,0) arc [chord=2:1];
\draw (0,0) node {$O$};
\end{tikzpicture}

\begin{tikzpicture}[chord b=1]
\foreach \a in {.1, .2, ..., 2}
  \draw[black] (0,0) arc [chord a=\a, chord do];
\draw (0,0) node {$O$};
\end{tikzpicture}
\end{document}

答案2

我认为可以让calc库完成大部分工作。然后可以给出带或不带维度的参数:

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{calc}
\tikzset{afro/.style args={(#1:#2)}{
  insert path={
    coordinate (@1)
    ($(@1)+(#1,#2)$) coordinate (@2)
    let \p1=($(@2)-(@1)$),
        \n1={(\x1*\x1+\y1*\y1)/(2*\y1)},
        \n2={acos((2*\x1*\y1)/(\x1*\x1+\y1*\y1))} in
    ($(@1)+(#1,0)$) arc (\n2:180-\n2:\n1)
}}}
\begin{document}
\begin{tikzpicture}
\draw (0,0) [afro=(2cm:1)];
\draw [red, ->] (0,0) -- (2cm,0);
\draw [red, ->] (0,0) -- (0,1cm);
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案3

问题的一部分在于对距离进行数学运算。pgfmath 使用 1=1pt 进行计算,而 tikz 在绘图时通常使用 1=1cm。它能够向 添加单位\pgfmathresult,但它所做的只是在解析时获取找到的第一个单位。

这是一个宏解决方案。如果您更喜欢使用按键而不是宏,那么您可以使用代码键来实现这一点。

\documentclass{article}
\usepackage{tikz}
%\usepackage{calc}% not needed inside tikz

\newcommand{\afro}[2]% #1 = a, #2 = b
 {\pgfextra{% needed inside a path
    \pgfmathparse{#1/1cm}%
    \let\a=\pgfmathresult
    \pgfmathparse{#2/1cm}%
    \let\b=\pgfmathresult
    \pgfmathparse{0.5*(\a*\a/\b + \b)}%
    \let\r=\pgfmathresult
    \pgfmathparse{acos(\a/\r)}%
    \let\angle=\pgfmathresult}%
  arc(\angle:180-\angle:\r cm)%
 }

\begin{document}

\begin{tikzpicture}
\draw[green] (0,0) arc (37:143:2.5cm);
\draw (0,0) node {$O$};
\end{tikzpicture}

\begin{tikzpicture}
\draw[red] (0,0) \afro{2cm}{1cm};
\draw (0,0) node {$O$};
\end{tikzpicture}

\end{document}

相关内容