Sphere Fitting program
Dependents: NineIMUAttitude_MadgwickFilter
SphereFitting.cpp
- Committer:
- aktk
- Date:
- 2020-12-26
- Revision:
- 1:05e1d9336ca8
- Parent:
- 0:bdae9d79b923
File content as of revision 1:05e1d9336ca8:
#include "SphereFitting.hpp" float const EPSILON = 1e-8; bool is_zero(float val); template<typename T> Sphere<T>::Sphere(T arg_cx, T arg_cy, T arg_cz) { cx = arg_cx; cy = arg_cy; cz = arg_cz; r = 1; } template<typename T> SphereFitting<T>::SphereFitting(T arg_cx, T arg_cy, T arg_cz) { P = new Sphere<T>(arg_cx, arg_cy, arg_cz); for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) X[i][j] = 0.0; for (int i = 0; i < 4; i++) Y[i] = 0.0; } template<typename T> SphereFitting<T>::~SphereFitting() { delete(P); } template<typename T> void SphereFitting<T>::addsample(T x, T y, T z) { X[0][0] += x * x; X[0][1] += x * y; X[0][2] += x * z; X[0][3] += x; X[1][0] += y * x; X[1][1] += y * y; X[1][2] += y * z; X[1][3] += y; X[2][0] += z * x; X[2][1] += z * y; X[2][2] += z * z; X[2][3] += z; X[3][0] += x; X[3][1] += y; X[3][2] += z; X[3][3] += 1; Y[0] += x *(x * x + y * y + z * z); Y[1] += y *(x * x + y * y + z * z); Y[2] += z *(x * x + y * y + z * z); Y[3] += x * x + y * y + z * z; } template<typename T> void SphereFitting<T>::solve() { float temp; // Completing making expression for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) X[i][j] *= 2; // Linear Algebrical Procedure for(int i = 0 ; i < 4 ; i++ ) { for(int j = i+1 ; j < 4 ; j++ ) { // Each proc lasts until X[i][j] is sufficiently small if(-EPSILON < X[i][j] && X[i][j] < EPSILON) break; for(int k = 0 ; k < 4 ; k++ ) X[i][k] += X[j][k]; Y[i] += Y[j]; } temp = X[i][i]; for(int j = i ; j < 4; j++ ) X[i][j] /= temp; Y[i] /= temp; for(int j = i+1 ; j < 4 ; j++ ) { temp = X[j][i]; for(int k = i ; k < 4 ; k++ ) X[j][k] -= temp * X[i][k]; Y[j] -= temp * Y[i]; } } for(int i = 4-1 ; i >= 0 ; i-- ) for(int j = i - 1 ; j >= 0 ; j-- ) Y[j] -= X[j][i] * Y[i]; P->cx = Y[0]; P->cy = Y[1]; P->cz = Y[2]; P->r = (short)sqrt((double)(Y[0]*Y[0] + Y[1]*Y[1] + Y[2]*Y[2] + 2*Y[3])); } template<typename T> void SphereFitting<T>::copy_param_to(T* ret_cx, T* ret_cy, T* ret_cz, T* ret_r) { *ret_cx = P->cx; *ret_cy = P->cy; *ret_cz = P->cz; if (ret_r != NULL) *ret_r = P->r; }