49 #include <Eigen/Dense>
57 using namespace UTILSLIB;
58 using namespace Eigen;
74 const VectorXf& x = points.col(0);
75 const VectorXf& y = points.col(1);
76 const VectorXf& z = points.col(2);
78 VectorXf point_means = points.colwise().mean();
80 VectorXf x_mean_free = x.array() - point_means(0);
81 VectorXf y_mean_free = y.array() - point_means(1);
82 VectorXf z_mean_free = z.array() - point_means(2);
85 A << (x.cwiseProduct(x_mean_free)).mean(), 2*(x.cwiseProduct(y_mean_free)).mean(), 2*(x.cwiseProduct(z_mean_free)).mean(),
86 0, (y.cwiseProduct(y_mean_free)).mean(), 2*(y.cwiseProduct(z_mean_free)).mean(),
87 0, 0, (z.cwiseProduct(z_mean_free)).mean();
89 Matrix3f A_T = A.transpose();
93 VectorXf sq_sum = x.array().pow(2)+y.array().pow(2)+z.array().pow(2);
94 b << (sq_sum.cwiseProduct(x_mean_free)).mean(),
95 (sq_sum.cwiseProduct(y_mean_free)).mean(),
96 (sq_sum.cwiseProduct(z_mean_free)).mean();
98 Vector3f
center = A.ldlt().solve(
b);
100 MatrixX3f tmp(points.rows(),3);
101 tmp.col(0) = x.array() -
center(0);
102 tmp.col(1) = y.array() -
center(1);
103 tmp.col(2) = z.array() -
center(2);
105 float r = sqrt(tmp.array().pow(2).rowwise().sum().mean());
120 return Sphere(Vector3f(), 0.0f);
127 MatrixXf rr_eigen(np,3);
128 VectorXf r0_eigen(3);
130 MatrixX3f dig_rr_eigen;
131 for (
int k = 0;
k < np;
k++) {
132 rr_eigen(
k, 0) = rr[
k][0];
133 rr_eigen(
k, 1) = rr[
k][1];
134 rr_eigen(
k, 2) = rr[
k][2];
137 if(rr_eigen.rows() < 0) {
138 std::cout <<
"Sphere::fit_sphere_to_points - No points were passed." << std::endl;
167 int report_interval = -1;
169 MatrixXf init_simplex;
170 VectorXf init_vals(4);
177 calculate_cm_ave_dist(rr, cm, R0);
179 init_simplex = make_initial_simplex( cm, simplex_size );
183 for (
int k = 0;
k < 4;
k++) {
184 init_vals[
k] = fit_eval(
static_cast<VectorXf
>(init_simplex.row(
k)), &user );
190 if(!SimplexAlgorithm::simplex_minimize<float>( init_simplex,
203 r0 = init_simplex.row(0);
204 R = opt_rad(r0, &user);
211 bool Sphere::report_func(
int loop,
const VectorXf &fitpar,
double fval)
216 const VectorXf& r0 = fitpar;
218 std::cout <<
"loop: " << loop <<
"; r0: " << 1000*r0[0] <<
", r1: " << 1000*r0[1] <<
", r2: " << 1000*r0[2] <<
"; fval: " << fval << std::endl;
225 void Sphere::calculate_cm_ave_dist(
const MatrixXf &rr, VectorXf &cm,
float &avep)
227 cm = rr.colwise().mean();
228 MatrixXf diff = rr.rowwise() - cm.transpose();
229 avep = diff.rowwise().norm().mean();
234 MatrixXf Sphere::make_initial_simplex(
const VectorXf &pars,
float size)
239 int npar = pars.size();
241 MatrixXf simplex = MatrixXf::Zero(npar+1,npar);
243 simplex.rowwise() += pars.transpose();
245 for (
int k = 1;
k < npar+1;
k++) {
246 simplex(
k,
k-1) += size;
254 float Sphere::fit_eval(
const VectorXf &fitpar,
const void *user_data)
261 const VectorXf& r0 = fitpar;
265 MatrixXf diff = user->rr.rowwise() - r0.transpose();
266 VectorXf one = diff.rowwise().norm();
268 float sum = one.sum();
269 float sum2 = one.dot(one);
271 F = sum2 - sum*sum/user->rr.rows();
274 std::cout <<
"r0: " << 1000*r0[0] <<
", r1: " << 1000*r0[1] <<
", r2: " << 1000*r0[2] <<
"; R: " << 1000*sum/user->rr.rows() <<
"; fval: "<<F<<std::endl;
281 float Sphere::opt_rad(
const VectorXf &r0,
const fitUserNew user)
283 MatrixXf diff = user->rr.rowwise() - r0.transpose();
284 return diff.rowwise().norm().mean();