A circle is a set of infinite points in two dimensions. However, a circle is clearly described by three of such points. The opposite direction is also correct as long as not all three points are on a straight line.
The question now is, how can we find the center C and radius r of a circle, given three points P1,P2 and P3? Typically, a circle at position (x′,y′) with radius r′ can be described with the equation
This top-down attempt works totally fine and can be implemeted straight ahead and is now part of Circle.js.
functioncircleFromThreePoints(p1, p2, p3) {
var x1 = p1.x;
var y1 = p1.y;
var x2 = p2.x;
var y2 = p2.y;
var x3 = p3.x;
var y3 = p3.y;
var a = x1 * (y2 - y3) - y1 * (x2 - x3) + x2 * y3 - x3 * y2;
var b = (x1 * x1 + y1 * y1) * (y3 - y2)
+ (x2 * x2 + y2 * y2) * (y1 - y3)
+ (x3 * x3 + y3 * y3) * (y2 - y1);
var c = (x1 * x1 + y1 * y1) * (x2 - x3)
+ (x2 * x2 + y2 * y2) * (x3 - x1)
+ (x3 * x3 + y3 * y3) * (x1 - x2);
var x = -b / (2 * a);
var y = -c / (2 * a);
return {
x: x,
y: y,
r: Math.hypot(x - x1, y - y1)
};
}
Geometric solution
An alternative way of deriving the solution is this: If we draw a line a through points P1 and P2 and another line b through points P2 and P3, it is obvious that their perpendicular lines crossing them at the middle of the points will meet exactly in the midpoint of the circle. The problem with this approach is, that the slope of the lines is ma=x2−x1y2−y1 and mb=x3−x2y3−y2. Therefore for the lines ya=ma(x−x1)+y1 and yb=mb(x−x2)+y2 and their perpendicular counter parts
we have discontinuities as long as we don't simplify the equation for x=2(mb−ma)mamb(y1−y3)+mb(x1+x2)−ma(x2+x3), which we got by setting the two equations equal. If we simplify the equations with Wolframalpha, we arrive at the same equations as as with the determinant solution.