10

In the classical arc command in TikZ, we specify an endpoint of the arc, followed by the initial and final angles, and finally the radius.

I would like to create a macro (if it doesn't already exist) that instead of specifying the angles and radius, specifies two distances, one horizontal and one vertical as shown below :

enter image description here

Note that this command is less powerful than the usual arc command as it only draws arcs that are symmetric with respect to some vertical axis. The conversion formulas are as follows : the radius is $\frac{a^2+b^2}{2b}$ and the initial angle is $cos^{-1}(\frac{2ab}{a^2+b^2})$.

Here is my failed attempt to implement this with tikzset (in the test file below, the two tikzpictures should be identical) :

\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}

Perhaps I should use pgfkeys ? Any help appreciated.

  • 1
    You are doing three essential things wrong with your afro style: 1. It is a style, it need to be applied inside [ and ]; 2. You declare #1:#2 but use (#1:#2); 3. You did not protect the parenthesis. You will need to do arc({acos(…)}:{180-acos(…)}:{((…))}) and \draw[red] (0,0) [afro=2cm:1cm]. – Qrrbrbirlbel Jun 13 '16 at 16:26
3

Here are some ideas.

The \ifpgfmathunitsdeclared test can be done after a \pgfmathparse operation (which \pgfmathsetmacro uses). The test will be true when at any place inside the mathematical evaluation something with a dimension has been used (either a TeX dimen or simply a statement like 2cm). If a unit is used either in #1 (a) or #2 (b) it is assumed that you want to draw your arc in the canvas coordinate system, otherwise in the local coordinate system. (Cf. (1, 2) vs (1cm, 2cm))

The calculation for the angle is also done before as it is used twice.

The /utils/exec key does nothing special, it justs executes the given code (like \pgfextra basically).


Note that the arc (…) path operator is deprecated. It is better to use the arc […] path operator, that way you can declare various options in an outer scope or use it in the every arc style.


More magic is needed if you want to use something like arc[a=2, b=1] without the auxiliary chord do style.

Code

\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}
  • There is also the math library where you can write something like \myRadius = <calculation>; but I don't think the unitsdeclared hook can be used properly. – Qrrbrbirlbel Jun 13 '16 at 17:00
4

I think it is possible to let the calc library do most of the work. Then parameters can be given with or without dimensions:

\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}

enter image description here

3

Part of the problem is doing math with distances. pgfmath uses 1=1pt to do calculations, while tikz typically uses 1=1cm when graphing. It has the ability to add units to \pgfmathresult, but all it does is take the first unit found while parsing.

This is a macro solution. You might be able to do this using a code key, if you are more comfortable with keys than macros.

\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}
  • It works, thanks. What I don't like about this solution is that the units are not specified in \afro{2}{1}. Is there a way to modify your solution so that \afro{2cm}{1cm} and \afro{2pt}{1pt} will each be interpreted the right way ? – user40960 Jun 14 '16 at 4:46
  • Yes. It is even possible to have it work both ways, but the code is tricky. See page 925 (section 89.1.2). – John Kormylo Jun 14 '16 at 13:19
  • Page 925 of which book ? I only know the LaTeX companion – user40960 Jun 14 '16 at 14:05
  • The tikz/pgf manual. You can download it from CTAN, but you probably already have a copy. Mine is in C:\Program Files\MiKTeX 2.9\doc\generic\pgf – John Kormylo Jun 14 '16 at 18:13
  • I created a folder that contains nothing but shortcuts to various LaTeX manual, plus a few files like source2e.pdf and symbols-a4.pdf. – John Kormylo Jun 14 '16 at 18:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.