A few months ago I wrote about several equations that come up in geometric calculations that all have the form of a determinant equal to 0, where one column of the determinant is all 1s.

The equation of a circle through three points (*x*_{1}, *y*_{1}), (*x*_{2}, *y*_{2}), and (*x*_{3}, *y*_{3}) has this form:

This is elegant equation, but it’s not in a form that’s ready to program. This post will start with the equation above and conclude with code.

Let *M*_{ij} be the determinant of the minor of the (*i*, j) element of the matrix above. That is, *M*_{ij} is the determinant of the 3 × 3 matrix obtained by deleting the *i*th row and *j*th column. Then we can expand the determinant above by minors of the last column to get

which we can rewrite as

A circle with center (*x*_{0}, *y*_{0}) and radius *r*_{0} has equation

By equating the coefficients *x* and *y* in the two previous equations we have

Next we expand the determinant minors in more explicit form.

Having gone to the effort of finding a nice expression for *M*_{11} we can reuse it to find *M*_{12} by the substitution

as follows:

And we can find *M*_{13} from *M*_{12} by reversing the role of the *x*s and *y*s.

Now we have concrete expressions for *M*_{11}, *M*_{12}, and *M*_{13}, and these give us concrete expressions for *x*_{0} and *y*_{0}.

To find the radius of the circle we simply find the distance from the center (*x*_{0}, *y*_{0}) to any of the points on the circle, say (*x*_{1}, *y*_{1}).

The following Python code incorporates the derivation above.

def circle_thru_pts(x1, y1, x2, y2, x3, y3): s1 = x1**2 + y1**2 s2 = x2**2 + y2**2 s3 = x3**2 + y3**2 M11 = x1*y2 + x2*y3 + x3*y1 - (x2*y1 + x3*y2 + x1*y3) M12 = s1*y2 + s2*y3 + s3*y1 - (s2*y1 + s3*y2 + s1*y3) M13 = s1*x2 + s2*x3 + s3*x1 - (s2*x1 + s3*x2 + s1*x3) x0 = 0.5*M12/M11 y0 = -0.5*M13/M11 r0 = ((x1 - x0)**2 + (y1 - y0)**2)**0.5 return (x0, y0, r0)

The code doesn’t use any loops or arrays, so it ought to be easy to port to any programming language.

For some inputs the value of *M*_{11} can be (nearly) zero, in which case the three points (nearly) lie on a line. In practice *M*_{11} can be nonzero and yet zero for practical purposes and so that’s something to watch out for when using the code.

The determinant at the top of the post is zero when the points are colinear. There’s a way to make rigorous the notion that in this case the points line on a circle centered at infinity.

**Update**: Equation of an ellipse or hyperbola through five points

It may be easier to take two perpendicular bisectors to find the centre, then draw the circle from there.

Meanwhile, I had an interesting case: it is possible to draw an ellipse of any aspect ratio and orientation through any set of three points (proof: affine transformation to make it a circle, then draw the circle and perform the inverse affine transformation). Testing this out with three “random” points and keeping the aspect ratio constant while varying the orientation, I found that the ellipses all passed through *four* common points (my original three plus an extra). A sample of one, but it may well be worth investigation.

Another thought: the condition for NOT being able to draw an ellipse through four points appears to be that one of the points lies inside the triangle defined by the other three points. If three of the points are collinear, the resulting conic is degenerate.