3

It has always bothered me that it's so hard to draw TikZ arcs by specifying the centre of the arc. Then I thought I have a good workaround by using the TikZ library math. Let's use it to draw an arc with center at the origin, and then put a dot at the origin.

\documentclass{standalone}

\usepackage{tikz}

\usetikzlibrary{math}

\begin{document}
    \begin{tikzpicture}
        \tikzmath{
            \angle  = 90;
            \radius = 1;
        }
        \draw
            ( canvas polar cs:
              radius = \radius
            , angle  = \angle
            )
            arc
            [ radius      = \radius
            , start angle = \angle
            , end angle   = 4*\angle
            ];
        \node[circle,fill] {};
    \end{tikzpicture}
\end{document}

This way I'm jumping to the start position of the arc using the polar coordinate system. \tikzmath allows me to reuse the lengths so I can specify exactly the same radius when I draw the arc (so when I fiddle around with radius values, I only need to do so in one point).

Clever, heh? Except it doesn't work:

enter image description here

It starts drawing at the origin although I specified the correct coordinates! What's going on? Maybe a dimension problem?

            \radius = 1cm;

That blows up the picture completely. Is my approach doomed? Note, that this works, though:

    \tikzmath{
        \angle  = 90;
    }
    \draw
        ( canvas polar cs:
          radius = 1cm
        , angle  = \angle
        )
        arc
        [ radius      = 1
        , start angle = \angle
        , end angle   = 4*\angle
        ];
    \node[circle,fill] {};

enter image description here

Ok, that's the right picture, but the code is silly! I don't want to enter every radius in my thousand pictures once with cm and once without! What do I do?

Turion
  • 4,622
  • If you use \draw (\angle:\radius) ... it works. But I am still struggling to understand what you want to achieve. –  Feb 15 '18 at 14:40
  • @marmot, I want to draw an arc by specifying/fixing its centre, and radius, and angles. – Turion Feb 15 '18 at 14:48
  • This is not a duplicate. My question was about dimensions. – Turion Feb 17 '18 at 13:19

5 Answers5

2

One possible way to do this is by explicitly declaring \radius to be a dimension, by using \newdimen:

\documentclass{standalone}

\usepackage{tikz}

\usetikzlibrary{math}

\begin{document}
    \begin{tikzpicture}
        \newdimen\radius
        \tikzmath{
            \angle  = 90;
            \radius = 1cm;
        }
        \draw
            ( canvas polar cs:
              radius = \radius
            , angle  = \angle
            )
            arc
            [ radius      = \radius
            , start angle = \angle
            , end angle   = 4*\angle
            ];
        \node[circle,fill] {};
    \end{tikzpicture}
\end{document}

Why no type error is thrown otherwise is beyond me.

Turion
  • 4,622
2

The manual states that the radius in canvas polar should be a dimension, so when you pass in a unitless number, I guess the default dimension, pt, is used. You can work around this for example by saying radius = \radius cm in the canvas polar cs coordinate.

Another option is to use declare function, as shown below.

\documentclass[border=5mm]{standalone}

\usepackage{tikz}

\usetikzlibrary{math}

\begin{document}
    \begin{tikzpicture}[
       declare function={
          R=1cm;
          a=90;
       }
    ]
        \tikzmath{
            \angle  = 90;
            \radius = 1;
        }
        \draw
            ( canvas polar cs:
              radius = \radius cm % <-- added cm here
            , angle  = \angle
            )
            arc
            [ radius      = \radius
            , start angle = \angle
            , end angle   = 4*\angle
            ];
        \node[circle,fill] {};

        \draw (2.5,0) node[circle,fill]{}
           ++(canvas polar cs:
               angle=a,
               radius=R) 
          % or equivalently
          % ++(a:R)
          arc[radius=R,
              start angle=a,
              end angle=4*a];
    \end{tikzpicture}
\end{document}

output of code

Torbjørn T.
  • 206,688
2

It's a bit of a faff, and might break something, but for fans of hacking, here is an around key which will draw the arc around the last point:

\documentclass[tikz,border=5]{standalone}
\makeatletter
\newif\iftikz@arc@around
\tikzset{around/.is if=tikz@arc@around, around=false}
\let\tikz@arc@around=\@empty
\def\tikz@arc@opt[#1]{%
  {%
    \tikzset{every arc/.try,#1}%
    \pgfkeysgetvalue{/tikz/start angle}\tikz@s
    \pgfkeysgetvalue{/tikz/end angle}\tikz@e
    \pgfkeysgetvalue{/tikz/delta angle}\tikz@d
    \ifx\tikz@s\pgfutil@empty%
      \pgfmathsetmacro\tikz@s{\tikz@e-\tikz@d}
    \else
      \ifx\tikz@e\pgfutil@empty%    
        \pgfmathsetmacro\tikz@e{\tikz@s+\tikz@d}
      \fi%
    \fi%
    \xdef\pgf@marshal{\noexpand%
    \tikz@do@arc{\tikz@s}{\tikz@e}
      {\pgfkeysvalueof{/tikz/x radius}}
      {\pgfkeysvalueof{/tikz/y radius}}
      {\iftikz@arc@around.\fi}}%
  }%
  \pgf@marshal%
  \tikz@arcfinal%  
}
\let\tikz@do@arc@orig=\tikz@do@arc
\def\tikz@do@arc#1#2#3#4#5{%
  \def\tikz@arc@around{#5}%
  \ifx\tikz@arc@around\@empty%
  \else%
    \let\tikz@pointpolar=\pgfpointpolarxy
    \pgfmathparse{#3}\ifpgfmathunitsdeclared\let\tikz@pointpolar=\pgfpointpolar\fi
    \pgfmathparse{#4}\ifpgfmathunitsdeclared\let\tikz@pointpolar=\pgfpointpolar\fi
    \pgfpathmoveto{\pgfpointadd{\pgfpoint{\tikz@lastx}{\tikz@lasty}}
      {\tikz@pointpolar{#1}{#3 and #4}}}%
  \fi%
  \tikz@do@arc@orig{#1}{#2}{#3}{#4}%
}
\makeatother
\begin{document}
\begin{tikzpicture}
\fill (0,0) circle [radius=0.05];
\draw [red]   (0,0) arc [radius=2, start angle=180, end angle=0];
\draw [green] (0,0) arc [radius=2, start angle=180, end angle=0, around];
\end{tikzpicture}
\end{document}

enter image description here

Mark Wibrow
  • 70,437
1

Something like this?

\documentclass{standalone}

\usepackage{tikz}

\usetikzlibrary{math}
\newcommand{\DrawArc}[5][]{%
\begin{scope}[shift={#2}]
\draw[#1]  (#4:#3)
            arc
            [ radius      = #3
            , start angle = #4
            , end angle   = #5
            ]; 
\end{scope}
}

\begin{document}
    \begin{tikzpicture}
    \draw[very thin,color=gray] (-3.9,-3.9) grid (3.9,3.9);
        \DrawArc{(2,1)}{1.2}{47}{167}
        \DrawArc[blue,ultra thick]{(-1,1)}{1.4}{47}{227}
    \end{tikzpicture}
\end{document}
  • Interesting... why does this not misinterpret the dimensions as it does in my example? – Turion Feb 15 '18 at 15:10
  • 1
    @Turion I did not play with tikzmath too much so far, but I know that \pgfmathsetmacro strips off dimensions. So I guess tikzmath does the same. (Note also that TikZ internally computes in pt units, see e.g. here. –  Feb 15 '18 at 15:16
  • seems plausible. Gosh, TeX needs static type checking. – Turion Feb 15 '18 at 15:22
1

Maybe if you use the pen move command it won't feel that hard; let's pick a random point and use it to draw an arc starting from 40 degrees with 1cm radius.

 \tikz\draw (rand,rand) node{A} ++(40:1cm) arc (40:-180:1cm);

enter image description here

If this is too verbose, you can make your own shorter syntax with an insert path or to path or any other shortcut.

percusse
  • 157,807