What's the easiest way to draw the arc defined by three points in TikZ?
Use the following code to draw the arc corresponding to the circle through (1,2), (3,4) and (2,4) and going anticlockwise from (1,2) to (2,4).
\documentclass[a4paper]{article}
\usepackage{tkz-euclide}
\usetkzobj{all}
\begin{document}
\begin{tikzpicture}
\tkzDefPoint(1,2){A}\tkzDefPoint(3,4){B}\tkzDefPoint(2,4){C}
\tkzCircumCenter(A,B,C)\tkzGetPoint{O}
\tkzDrawArc(O,A)(C)
\end{tikzpicture}
\end{document}
Keep in mind that I don't actually know TikZ. I did what you said: I used pgf math to work out the values for the angles and the radius and then packaged it up into a simple macro.
\documentclass[border=10]{standalone}
\usepackage{tikz}
\def\drawcirculararc(#1,#2)(#3,#4)(#5,#6){%
\pgfmathsetmacro\cA{(#1*#1+#2*#2-#3*#3-#4*#4)/2}%
\pgfmathsetmacro\cB{(#1*#1+#2*#2-#5*#5-#6*#6)/2}%
\pgfmathsetmacro\cy{(\cB*(#1-#3)-\cA*(#1-#5))/%
((#2-#6)*(#1-#3)-(#2-#4)*(#1-#5))}%
\pgfmathsetmacro\cx{(\cA-\cy*(#2-#4))/(#1-#3)}%
\pgfmathsetmacro\cr{sqrt((#1-\cx)*(#1-\cx)+(#2-\cy)*(#2-\cy))}%
\pgfmathsetmacro\cA{atan2(#1-\cx,#2-\cy)}%
\pgfmathsetmacro\cB{atan2(#5-\cx,#6-\cy)}%
\pgfmathparse{\cB<\cA}%
\ifnum\pgfmathresult=1
\pgfmathsetmacro\cB{\cB+360}%
\fi
\draw (#1,#2) arc (\cA:\cB:\cr);%
}
\begin{document}
\begin{tikzpicture}
\drawcirculararc(0,0)(1,0)(1,1);
\end{tikzpicture}
\end{document}
It isn't terribly hard to work out the origin and the radius using
r2 = (xi - x)2 + (yi - y)2
for i in {1,2,3}.
The macro assumes that the points are entered counterclockwise. It probably fails in some cases, since I didn't test it very extensively.
I guess I should point out that that the computation of the center of the circle, (\cx
,\cy
) depends on some quantities not being zero. One can write down three linear equations relating \cx
and \cy
. Any two of them suffice for solving (of course) the system so there are three possible choices. I didn't check, but I believe it's impossible for the relevant quantities to all be zero (unless your points are colinear, but then you don't have a circle).
If one were so inclined, one could generalize the computation of \cx
and \cy
depending on which two equations are used and then just pick one for which the denominators are not zero. Since there's a better solution, I didn't bother, but I guess I could if someone actually cares.
Edit: The original code didn't work with TikZ 3.00
since atan2(x,y)
has been redefined: its first and second arguments have to be switched. This edit fixes this.
Just for completeness, a tikz
solution which does not use tikz-euclide
, but instead does all the calculations through calc
library and let..in
syntax. Macro \arcThroughThreePoints
requires the three coordinates to be given in counter-clockwise order.
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\newcommand{\arcThroughThreePoints}[4][]{
\coordinate (middle1) at ($(#2)!.5!(#3)$);
\coordinate (middle2) at ($(#3)!.5!(#4)$);
\coordinate (aux1) at ($(middle1)!1!90:(#3)$);
\coordinate (aux2) at ($(middle2)!1!90:(#4)$);
\coordinate (center) at ($(intersection of middle1--aux1 and middle2--aux2)$);
\draw[#1]
let \p1=($(#2)-(center)$),
\p2=($(#4)-(center)$),
\n0={veclen(\p1)}, % Radius
\n1={atan2(\x1,\y1)}, % angles
\n2={atan2(\x2,\y2)},
\n3={\n2>\n1?\n2:\n2+360}
in (#2) arc(\n1:\n3:\n0);
}
\begin{document}
\begin{tikzpicture}
\coordinate (A) at (3,1);
\coordinate (B) at (1,2);
\coordinate (C) at (-2,-2);
\arcThroughThreePoints{A}{B}{C};
\foreach \p in {A,B,C,center}
\fill[red] (\p) circle(2pt);
\end{tikzpicture}
\end{document}
Edit: With TikZ 3.00
and later, the previous code is now:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\newcommand{\arcThroughThreePoints}[4][]{
\coordinate (middle1) at ($(#2)!.5!(#3)$);
\coordinate (middle2) at ($(#3)!.5!(#4)$);
\coordinate (aux1) at ($(middle1)!1!90:(#3)$);
\coordinate (aux2) at ($(middle2)!1!90:(#4)$);
\coordinate (center) at ($(intersection of middle1--aux1 and middle2--aux2)$);
\draw[#1]
let \p1=($(#2)-(center)$),
\p2=($(#4)-(center)$),
\n0={veclen(\p1)}, % Radius
\n1={atan2(\y1,\x1)}, % angles
\n2={atan2(\y2,\x2)},
\n3={\n2>\n1?\n2:\n2+360}
in (#2) arc(\n1:\n3:\n0);
}
\begin{document}
\begin{tikzpicture}
\coordinate (A) at (3,1);
\coordinate (B) at (1,2);
\coordinate (C) at (-2,-2);
\arcThroughThreePoints{A}{B}{C};
\foreach \p in {A,B,C,center}
\fill[red] (\p) circle(2pt);
\end{tikzpicture}
\end{document}
I guess this answer does not qualifies as "the easiest way", as the title of the question requests, but it shows some nifty tricks.