6

Consider n point $(x_1,y_1), (x_2,y_2),\ldots, (x_n,y_n)$. For $n = 3$ it is easy to find the center of the circle passing through the three points. I wanted find the approximate center of the circle passing through more than three points.

The application is as follows. I have circles on a sheet of metal. I can poll different points on the circle to get the their co-ordinates. By polling three points on every circle I can predict the co-ordinates of the center. But I wanted to improve the accuracy of the prediction. A Google search reveals only the center of the passing through three points.

Edit 1: In response to Hoda's comment, I am adding that the measurements related to the points on the circle have errors. The objective is to minimize the error in the position of the center by polling more points on the circle.

  • What do you mean by "improving the accuracy of the prediction"? With only three points you can determine where exactly the center is. If you have more points and you are sure that the all lie on a circle, choosing any three of them would determine the exact position. – Hoda Feb 04 '14 at 01:27
  • 2
    I thought it was obvious that, given the context, the measurements will have errors. My apologies. – Shashank Sawant Feb 04 '14 at 01:59
  • Do you have any statistical knowledge about the errors? – Hoda Feb 04 '14 at 02:01
  • I am assuming normal distribution. But I really really don't suppose that it is necessary. I think this problem can be solved in the general context that it was originally stated. – Shashank Sawant Feb 04 '14 at 02:03
  • 1
    There are a lot of hits for "circle fitting" on the web. –  Feb 04 '14 at 02:22
  • Yeah... that really opened the flood gates... Thanks! – Shashank Sawant Feb 04 '14 at 02:23
  • 1
    What is the problem with the naive method: if you have $n$ sample points, take all combination of $3$ points amongst them and for each triple, compute the center of the circle passing through these points. Then estimate the real center by taking the average of the computed centers. With normal distributions of error and CLT, it should give you an unbiased estimator of the real center. No? – Taladris Feb 04 '14 at 02:30
  • That sounds awesome... I think I will try writing a code. – Shashank Sawant Feb 04 '14 at 02:32
  • 2
    @Taladris: The paper "A Few Methods for Fitting Circles to Data" discusses the drawbacks of the naive $n\choose3$-intersections method. For example, "it fails if any three of the points are collinear", and "is also very unstable in that small changes in relatively close points can drastically change some of the approximating centers". –  May 08 '14 at 18:24
  • It is essential to know if there are outliers (i.e. extra points in fact not belonging to the circle, which pollute the data set). If yes, you will need to resort to so-called robust methods, such as RANSAC. Least-squares lives very poorly with outliers. –  Apr 05 '19 at 09:46

10 Answers10

7

One can find on the web several methods of cercle fitting. Most of them are itterative. A straightforward method, without trial and error process, is described pp.12-13 in the paper "Régressions coniques, quadriques, circulaire, ..." : http://www.scribd.com/JJacquelin/documents No need to read the theoretical part written in French. Just apply the formulas (1), (2) and (3) which allows to very easily compute the coordinates of the center and the radius of the fitted circle. A numerical example is provided page 15.

JJacquelin
  • 66,221
  • 3
  • 37
  • 87
2

Introducing a bias, consider the equations $$F_i=(X-x_i)^2+(Y-y_i)^2-r^2=0$$ You can write $$F_j-F_i=2(x_i-x_j) X+2(y_i-y_j)Y=(x_i^2+y_i^2)-(x_j^2+y_j^2)$$ This is identical to what Steven Taschuk wrote.

Generate all equations for $(i=1,2,\cdots,n-1)$, $(j=i+1,i+2,\cdots,n)$. This will create $\frac{n(n-1)}2$ equations and defining the regressors you basically face the problem of a least square fit (with no intercept) and the calculation is immediate (using matrix will make the problem very easy). So you will have very good estimates of the coordinates of the center and the full nonlinear regression will converge in a couple of iterations since averaging all the $F_i$'s, you have a good estimates of $r^2$ then $r$.

Applied to the data points I used in my previous answer, this procedure leads to $X=5.40887$, $Y=8.42447$. The average radius is $r=3.41043$.

Now, any procedure will solve in a couple of iterations to $$\begin{array}{clclclclc} \text{} & \text{Estimate} & \text{Standard Error} & \text{Confidence Interval} \\ X & 5.39989 & 0.0928415 & \{5.10443,5.69535\} \\ Y & 8.42763 & 0.128379 & \{8.01907,8.83619\} \\ r & 3.41031 & 0.0760165 & \{3.16839, 3.65223\} \\ \end{array}$$

2

Recalling the circle equation with center $(h,k)$ and radius $r$

$$ (x-h)^2+(y-k)^2 = r^2 .$$

The above equation has three unknowns which can be determined uniquely by knowing three points lie on the circle. However, if you have more than three points, then you may need to appeal to least squares method. See related technique.

2

Assuming normally distributed errors, a maximum-likelihood estimate for the circle parameters $(x_0, y_0, r)$ is one that minimizes the sum of the squared distances from the circle: $$ SS(x_0,y_0,r)=\sum_{i=1}^{n}\left(\sqrt{(x_i-x_0)^2 + (y_i-y_0)^2}-r\right)^2. $$ Taking the derivative with respect to $r$ gives $$ 0=\frac{\partial}{\partial r}SS(x_0,y_0,r)=-2\left(\sum_{i=1}^{n}\sqrt{(x_i-x_0)^2+(y_i-y_0)^2}-nr\right), $$ so $$ r^{*}=\frac{1}{n}\sum_{i=1}^{n}\sqrt{(x_i-x_0)^2+(y_i-y_0)^2}. $$ A numerical search for coordinates $(x_0,y_0)$ that minimize $SS(x_0,y_0,r^*)$ should be relatively straightforward.

mjqxxxx
  • 41,358
2

The answer given by mjqxxxx is very interesting. What he shows is that the problem can be reduced to $x_0$ and $y_0$ since $r$ is eliminated. Keeping the same objective function as the one he proposed, just use Newton-Raphson method to compute the values of $x_0$ and $y_0$ for which the derivatives cancel. $$\frac{\partial}{\partial x_0}SS(x_0,y_0,r)=0$$ $$\frac{\partial}{\partial y_0}SS(x_0,y_0,r)=0$$

Since I suppose that you have "reasonable" estimates of the variables, the convergence will be quite easy. You could even be lazy and use numerical derivatives to compute the Jacobian of the system.

I applied the method using six data points : $(2.5,6.5), (2.0,8.5), (4.0,11.5), (7.5,11.0), (9.0,9.0), (8.0,6.5)$.
The calculations solved in three iterations and the circle is such that $r=3.41031$, $x_0=5.39989$, $y_0=8.42763$.

If you apply to the same data the method proposed by JJacquelin, you directly arrive to $r=3.41287$, $x_0=5.40887$, $y_0=8.42447$. This method is from far superior to what I proposed since it is a direct and explicit method which just requires the computation of a few sums over the coordinates of the data points.

  • how do you apply NR method in this case since we have three unknown r , x0 , y0 in one equation. – David Jul 04 '15 at 02:05
  • You have three equations which are the derivatives wrt tp $x_0,y_0,r$. You can eliminate $r$ using what mjqxxxx suggested. So we are left with two equations. – Claude Leibovici Jul 04 '15 at 02:24
  • Thanks got it. What solver do you use to solve the remaining 2 equations. I mean is analytic solution exit or you have to use numerical solver ? – David Jul 04 '15 at 06:24
  • Numerical solver for this formulation. I shall post another answer showing what you also could do. – Claude Leibovici Jul 04 '15 at 08:21
1

The perpendicular bisector of the line segment joining point $(x_i,y_i)$ and point $(x_j,y_j)$ has equation $$ (x_i-x_j)x+(y_i-y_j)y = \tfrac12(x_i^2+y_i^2-x_j^2-y_j^2) $$ If all the given points fell on one circle, all these lines would intersect, and you could just solve the system. If they do not intersect, you have an overdetermined system of linear equations, for which you can compute an approximate solution by least squares.

This method has the advantage of only using very standard tools.

0

You have $n$ equations that look like this, with $x_i$ and $y_i$ being the known points, $a$ and $b$ being the unknown center coordinates, and $r$ the unknown radius. $$ (x_i - a)^2 + (y_i - b)^2 - r^2 = 0$$

Multiply out all the squared differences, and consolidate all the constant terms on the right. Now you have $n$ equations that look like this:

$$e_i a + a^2 + f_i b + b^2 - r^2 = g_i$$

Subtract the first equation from all the rest. Now you have the first equation same as before, but the rest for $2 \le i \le n$ look like: $$(e_i - e_1)a + (f_i - f_1)b = g_i - g_1$$

Since $n \gt 3$, you have at least $3$ of these linear equations with 2 unknowns, which you can solve for $a$ and $b$, giving you an overdetermined linear system. Rewrite this system as $\mathrm{A}x = g$, then you can solve for $x$ in a least squares sense with $x = (\mathrm{A}^T\mathrm{A})^{-1}\mathrm{A}^Tg$.

Once you have estimated $a$ and $b$, you can easily estimate $r$ with root-sum-square on all the calculated distances between the $(x_i,y_i)$ and $(a,b)$.

NovaDenizen
  • 4,216
  • 15
  • 23
0

First you need to define what your metric for error is, and then you can talk about minimizing it. For example, in simple linear regression, the error is measured by summing the squares of the vertical displacement from each known datum $(x_i,y_i)$ to the line. But in exponential regression, the error is measured by summing the squares of the logarithms of the ratios between the known data $(x_i,y_i)$ and the exponential curve.

I can imagine several candidates here for quantifying error. Simply summing the distances from the data to the circle (where by distance, I mean shortest distance). Or summing the squares of these distances. The somehow doesn't feel right though, since it seems reasonable to make a point at the circle's center contribute a lot more error than one which is one radius removed externally from the circle. Some metric that put the center of the circle infinitely far away from the circle itself might be nice.

2'5 9'2
  • 54,717
0

Since you did not specify in which way the center should be uniquely defined, I'll just present some thoughts based on the observation that the usual method of finding the center of a circle through three points is really nothing else but finding the intersection of two or three perpendicular bisectors of the lines connecting those points.

One method often used in triangulation on a map (using a magnetic compass etc) is to take more than the strictly necessary two lines, and take all the intersections as approximations to the true position. You could do some statistical analysis to discard outliers, you could take the barycenter of their convex hull, or simply their average.

0

Just including a python (v2.7) code below (with the least squares method) for anyone who wants to try it out using a computer:

# Original source: http://www.had2know.com/academics/best-fit-circle-least-squares.html
# Notes: I have slightly modified the original code to suit my ends. There are 
# quite a few errors on the source link. Try out their example and it should be clear.

import numpy as np

# Initialize the lists for the abscissae and the ordinates
x_l=[]
y_l=[]
# Get the x and y coordinates of the points
while True:
    x_temp = raw_input("Enter the x-cordinate (press n to initiate fitting):\n")                       
    if x_temp.strip() == "n":
        break
    y_temp = raw_input("Enter the y-cordinate:\n")
    print "------------------------------------------------------"
    x_l.append(float(x_temp))
    y_l.append(float(y_temp))
nop = len(x_l)                          # number of points

# Primary raw material
x = np.array(x_l)                       #numpy array
y = np.array(y_l)                       #numpy array

x_y = np.multiply(x,y)                  #elementwise multiplication
x_2 = np.square(x)                      #elementwise square
y_2 = np.square(y)                      #elementwise square

# Secondary raw material
x_2_plus_y_2 = np.add(x_2,y_2)          #elementwise addition
x__x_2_plus_y_2 = np.multiply(x,x_2_plus_y_2)   #elementwise multiplication
y__x_2_plus_y_2 = np.multiply(y,x_2_plus_y_2)   #elementwise multiplication

# Summations (by default the result of summation is integer)
sum_x = x.sum(dtype=float)
sum_y = y.sum(dtype=float)
sum_x_2 = x_2.sum(dtype=float)
sum_y_2 = y_2.sum(dtype=float)
sum_x_y = x_y.sum(dtype=float)
sum_x_2_plus_y_2 = x_2_plus_y_2.sum(dtype=float)
sum_x__x_2_plus_y_2 = x__x_2_plus_y_2.sum(dtype=float)
sum_y__x_2_plus_y_2 = y__x_2_plus_y_2.sum(dtype=float)

# Comment the line below; don't delete. Use for debugging.
# print sum_x,sum_y,sum_x_2,sum_y_2,sum_x_y,sum_x_2_plus_y_2,sum_x__x_2_plus_y_2,sum_y__x_2_plus_y_2

m3b3 = np.array([[sum_x_2,sum_x_y,sum_x],
        [sum_x_y,sum_y_2,sum_y],
        [sum_x,sum_y,nop]])
invm3b3 = np.linalg.inv(m3b3)
m3b1 = np.array([sum_x__x_2_plus_y_2,sum_y__x_2_plus_y_2,sum_x_2_plus_y_2])
A=np.dot(invm3b3,m3b1)[0]
B=np.dot(invm3b3,m3b1)[1]
C=np.dot(invm3b3,m3b1)[2]
CenterX = A/2
CenterY = B/2
Radius = np.sqrt(4*C+A**2+B**2)/2
print "Center's x-cordinate is :",CenterX,"\nCenter's y-cordinate is : ",CenterY,"\nCircle's radius is : ",Radius