3

This question already has an answer here:

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?

marked as duplicate by Kpym, Stefan Pinnow, Phelype Oleinik, egreg tikz-pgf Feb 16 '18 at 22:45

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • If you use \draw (\angle:\radius) ... it works. But I am still struggling to understand what you want to achieve. – user121799 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
1

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

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

1

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.

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. – user121799 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.

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