In a space coordinate system, the radii and centers of multiple slice circles sliced along the Z axis are known, and the slice circles are used to fit the center and radius of a sphere

This problem can be solved using the method of least squares. Suppose we know

N

N

N sliced circles, the th

i

i

The radius of i sliced circles is

r

i

r_i

ri?, the coordinates of the center of the circle are

(

x

i

,

the y

i

,

z

i

)

(x_i,y_i,z_i)

(xi?, yi?, zi?). The coordinates of the center of the sphere we want to fit are

(

x

0

,

the y

0

,

z

0

)

(x_0,y_0,z_0)

(x0?,y0?,z0?), with a radius of

r

r

r.

for the first

i

i

i sliced circles, we can write the equation of the plane in which they lie:

(

x

?

x

i

)

2

+

(

the y

?

the y

i

)

2

+

(

z

?

z

i

)

2

=

r

i

2

(x-x_i)^2 + (y-y_i)^2 + (z-z_i)^2=r_i^2

(x?xi?)2 + (y?yi?)2 + (z?zi?)2=ri2?

Simplified:

x

2

+

the y

2

+

z

2

?

2

x

x

i

?

2

the y

the y

i

?

2

z

z

i

+

(

x

i

2

+

the y

i

2

+

z

i

2

?

r

i

2

)

=

0

x^2 + y^2 + z^2-2xx_i-2yy_i-2zz_i + (x_i^2 + y_i^2 + z_i^2-r_i^2)=0

x2 + y2 + z2?2xxi2yyi2zzi? + (xi2? + yi2? + zi2ri2?)=0

We can write the above equation in vector form:

[

2

x

i

2

the y

i

2

z

i

?

1

]

[

x

the y

z

?

1

]

x

i

2

+

the y

i

2

+

z

i

2

?

r

i

2

\begin{bmatrix} 2x_i & amp; 2y_i & amp; 2z_i & amp; -1 \end{bmatrix} \begin{bmatrix} x \ y \ z \ -1 \end{bmatrix} x_i ^2 + y_i^2 + z_i^2-r_i^2

[2xi2yi2zi?1?][x y z ?1?]xi2? + yi2? + zi2ri2?

we can combine all

N

N

N plane equations are written in matrix form:

[

2

x

1

2

the y

1

2

z

1

?

1

2

x

2

2

the y

2

2

z

2

?

1

?

?

?

?

2

x

N

2

the y

N

2

z

N

?

1

]

[

x

the y

z

?

1

]

[

x

1

2

+

the y

1

2

+

z

1

2

?

r

1

2

x

2

2

+

the y

2

2

+

z

2

2

?

r

2

2

?

x

N

2

+

the y

N

2

+

z

N

2

?

r

N

2

]

\begin{bmatrix} 2x_1 & amp; 2y_1 & amp; 2z_1 & amp; -1 \ 2x_2 & amp; 2y_2 & amp; 2z_2 & amp; -1 \ \vdots & amp; \vdots & amp; \vdots & amp; \vdots \ 2x_N & amp; 2y_N & amp; 2z_N & amp; -1 \ \end{bmatrix} \begin{bmatrix} x \ y \ z \ -1 \end{bmatrix} \begin{bmatrix} x_1^2 + y_1^2 + z_1^2-r_1^2 \ x_2^2 + y_2^2 + z_2^2-r_2^2 \ \vdots \ \ x_N^2 + y_N^2 + z_N^2-r_N^2 \ \end{bmatrix}

[2x12y12z1?1 2x22y22z2?1 ? 2xN2yN2zN?1 ?][x y z ?1?][ + y12? + z12r12? x22? + y22? + z22r22? ? xN2? + yN2? + zN2rN2? ]

Let the above matrix be

A

A

A, the vector is

b

b

b, the unknown vector is

x

x

x, then the above equation can be written as

A

x

=

b

Ax=b

of the form Ax=b. Our goal is to minimize the residual by

A

x

?

b

|Ax-b|

∣Ax?b∣ to get

x

x

The optimal solution for x, which is the coordinates of the center of the sphere

(

x

0

,

the y

0

,

z

0

)

(x_0,y_0,z_0)

(x0?,y0?,z0?) and radius

r

r

r.

The solution of the least squares method is relatively simple, directly solving

x

=

(

A

T

A

)

?

1

A

T

b

x=(A^TA)^{-1}A^Tb

x=(ATA)?1ATb is enough. Will

x

x

x is split into

(

x

0

,

the y

0

,

z

0

,

r

)

(x_0,y_0,z_0,r)

(x0?,y0?,z0?,r), the coordinates and radius of the center of the sphere can be obtained.

|The center and radius of the sphere can be fitted using the method of least squares. The specific implementation steps are as follows:
1. Define a sphere structure, including the center coordinates and radius:

struct Sphere {<!-- -->
    double x, y, z; // coordinates of the center of the sphere
    double r; // radius
};

2. Define a function, the input is the radius and center of multiple sliced circles, and the output is the fitted sphere structure:

Sphere fitSphere(vector<pair<double, tuple<double, double, double>>> circles) {<!-- -->
    // Initialize matrix A and vector b
    Eigen::MatrixXd A(circles. size(), 4);
    Eigen::VectorXd b(circles. size());
    for (int i = 0; i < circles. size(); i ++ ) {<!-- -->
        double r = circles[i].first;
        double x = get<0>(circles[i].second);
        double y = get<1>(circles[i].second);
        double z = get<2>(circles[i].second);
        A(i, 0) = 2 * x;
        A(i, 1) = 2 * y;
        A(i, 2) = 2 * z;
        A(i, 3) = -1;
        b(i) = x * x + y * y + z * z - r * r;
    }


    // Solve using the least squares method
    Eigen::VectorXd x = A.jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(b);

    // Convert the solution result to a sphere structure
    Sphere sphere;
    sphere.x = x(0);
    sphere.y = x(1);
    sphere.z = x(2);
    sphere.r = std::sqrt(x(0) * x(0) + x(1) * x(1) + x(2) * x(2) - x(3));

    return sphere;
}

3. Call the above function for fitting:

vector<pair<double, tuple<double, double, double>>> circles; // Radius and center of slice circle
// add sliced circle
circles.push_back(make_pair(1.0, make_tuple(0.0, 0.0, 0.0)));
circles.push_back(make_pair(2.0, make_tuple(0.0, 0.0, 1.0)));
circles.push_back(make_pair(3.0, make_tuple(0.0, 0.0, 2.0)));
// fit the sphere
Sphere sphere = fitSphere(circles);
// output result
cout << "Sphere center: (" << sphere.x << ", " << sphere.y << ", " << sphere.z << ")" << endl ;
cout << "Sphere radius: " << sphere.r << endl;