Lengths and coordinates in TikZ arcs [duplicate]

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;
}
\draw
( canvas polar cs:
, angle  = \angle
)
arc
, 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: It starts drawing at the origin although I specified the correct coordinates! What's going on? Maybe a dimension problem?

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

\tikzmath{
\angle  = 90;
}
\draw
( canvas polar cs:
, angle  = \angle
)
arc
[ radius      = 1
, start angle = \angle
, end angle   = 4*\angle
];
\node[circle,fill] {}; 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 StackExchange.ready(function() { if (StackExchange.options.isMobile) return; $('.dupe-hammer-message-hover:not(.hover-bound)').each(function() { var$hover = $(this).addClass('hover-bound'),$msg = $hover.siblings('.dupe-hammer-message');$hover.hover( function() { $hover.showInfoMessage('', { messageElement:$msg.clone().show(), transient: false, position: { my: 'bottom left', at: 'top center', offsetTop: -7 }, dismissable: false, relativeToBody: true }); }, function() { StackExchange.helpers.removeMessages(); } ); }); }); Feb 16 '18 at 22:45

• 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

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;
}
\draw
( canvas polar cs:
, angle  = \angle
)
arc
, start angle = \angle
, end angle   = 4*\angle
];
\node[circle,fill] {};

\draw (2.5,0) node[circle,fill]{}
++(canvas polar cs:
angle=a,
% or equivalently
% ++(a:R)
start angle=a,
end angle=4*a];
\end{tikzpicture}
\end{document} 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}
{\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
{\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} 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}
\tikzmath{
\angle  = 90;
}
\draw
( canvas polar cs:
, angle  = \angle
)
arc
, start angle = \angle
, end angle   = 4*\angle
];
\node[circle,fill] {};
\end{tikzpicture}
\end{document}

Why no type error is thrown otherwise is beyond me.

Something like this?

\documentclass{standalone}

\usepackage{tikz}

\usetikzlibrary{math}
\newcommand{\DrawArc}[]{%
\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
• @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

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); If this is too verbose, you can make your own shorter syntax with an insert path or to path or any other shortcut.