Fortunately for you there is indeed a "direct" solution to the sphere fitting problem.
Expanding and rearranging the Cartesian equation of the sphere:
(x - c_x)² + (y - c_x)² + (z - c_z)² = r²
you get:
2.x.c_x + 2.y.c_y + 2.z.c_z + r² - c_x² - c_y² - c_z² = x² + y² + z²
The left part includes the sphere parameters (center and radius) and the right part is the sum of the squared coordinates of the points.
Setting:
t = r² - c_x² - c_y² - c_z²
allows to write the fitting problem as a linear least squares problem (which is quite easily solved) A.x = b with x = [c_x, c_y, c_z, t] (not the same x as for the points!).
In python, assuming that your points are stored in a numpy array of shape (n, 3), you'd have:
import numpy as np
def fit_sphere(points):
# Coefficient matrix and values
A = np.column_stack((2*points, np.ones(len(points))))
b = (points**2).sum(axis=1)
# Solve A x = b
x, res, _, _ = np.linalg.lstsq(A, b, rcond=None)
# Sphere parameters
center = x[:3]
radius = np.sqrt(x[0]**2 + x[1]**2 + x[2]**2 + x[3])
return (center, radius), res
If you're interested to see how it works you can check these tutorials.
Cheers !
sum[i=0..n]( |P_i - C|^2 - r^2 )^2
instead, so your derivatives will behave properly. And, because your problem will be nonlinear in any case, you are probably stuck with some form of iteration. – Extensor