在 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
\pgfmathsetmacro
2cm
#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}