20 #include "../helper/helpFuncs.h" 23 #include <gsl/gsl_blas.h> 24 #include <gsl/gsl_linalg.h> 46 gsl_permutation *p = gsl_permutation_alloc(A->size1);
52 tmpA = gsl_matrix_alloc(A->size1, A->size2);
53 gsl_matrix_memcpy(tmpA, A);
57 gsl_linalg_LU_decomp(tmpA, p, &signum);
58 det = gsl_linalg_LU_det(tmpA, signum);
59 gsl_permutation_free(p);
61 gsl_matrix_free(tmpA);
68 const Point3D &r1,
const Point3D &r2, std::vector<std:: vector<float> > &m)
70 gsl_matrix *mm = gsl_matrix_alloc(3,3);
74 for(
auto ui=0;ui<3;ui++)
77 for(
auto uj=0;uj<3;uj++)
78 m[ui][uj] =gsl_matrix_get(mm,ui,uj);
108 Point3D doubleCross1,doubleCross2;
113 a = gsl_matrix_alloc(3,3);
114 b = gsl_matrix_alloc(3,3);
117 for(
unsigned int ui=0;ui<3;ui++)
120 gsl_matrix_set(a,ui,0,r1[ui]);
121 gsl_matrix_set(a,ui,1,rCross[ui]);
122 gsl_matrix_set(a,ui,2,doubleCross1[ui]);
125 gsl_matrix_set(b,0,ui,ur1[ui]);
126 gsl_matrix_set(b,1,ui,urCross[ui]);
127 gsl_matrix_set(b,2,ui,doubleCross2[ui]);
136 gsl_blas_dgemm (CblasNoTrans, CblasNoTrans,
148 const std::vector<float> &weights,gsl_matrix* &R)
152 ASSERT(rotated.size() == unrotated.size());
154 ASSERT(rotated.size() >=2);
156 if(rotated.size() < 2)
160 R=gsl_matrix_alloc(3,3);
163 ASSERT(R->size1 == 3 && R->size2 ==3);
173 gsl_matrix *B = gsl_matrix_alloc(3,3);
174 gsl_matrix_set_all(B,0);
176 v1= gsl_vector_alloc(3);
177 v2= gsl_vector_alloc(3);
179 for(
auto ui=0u; ui<unrotated.size();ui++)
181 ASSERT(TOL_EQ(unrotated[ui].sqrMag(),1));
182 ASSERT(TOL_EQ(rotated[ui].sqrMag(),1));
183 for(
auto uj=0u;uj<3;uj++)
185 v1->data[uj] = unrotated[ui][uj];
186 v2->data[uj] = rotated[ui][uj];
190 gsl_blas_dger(weights[ui],v1, v2, B);
200 gsl_matrix *V = gsl_matrix_alloc(B->size2,B->size2);
201 gsl_vector *S = gsl_vector_alloc(B->size2);
202 gsl_vector *work = gsl_vector_alloc(B->size2);
205 gsl_linalg_SV_decomp (B, V, S, work);
207 gsl_vector_free(work);
214 gsl_matrix *M=gsl_matrix_alloc(3,3);
215 gsl_matrix_set_all(M,0);
218 gsl_matrix_set(M,0,0,1);
219 gsl_matrix_set(M,1,1,1);
224 gsl_matrix *T=gsl_matrix_alloc(3,3);
228 gsl_matrix_transpose(V);
234 gsl_matrix_transpose(R);
251 gsl_matrix *R = gsl_matrix_alloc(3,3);
253 double versin = 1.0-cos(theta);
254 double ct = cos(theta);
255 double st= sin(theta);
258 for(
auto ui=0;ui<3;ui++)
259 gsl_matrix_set(R,ui,ui,ct+norm[ui]*norm[ui]*versin);
262 gsl_matrix_set(R,0,1,norm[0]*norm[1]*versin - norm[2]*st);
263 gsl_matrix_set(R,0,2,norm[0]*norm[2]*versin + norm[1]*st);
266 gsl_matrix_set(R,1,0,norm[1]*norm[0]*versin+norm[2]*st);
267 gsl_matrix_set(R,1,2,norm[1]*norm[2]*versin-norm[0]*st);
270 gsl_matrix_set(R,2,0,norm[2]*norm[0]*versin-norm[1]*st);
271 gsl_matrix_set(R,2,1,norm[2]*norm[1]*versin+norm[0]*st);
281 bool testRotationAlgorithms();
282 bool testTRIADRotation();
287 bool testRotationAlgorithms()
289 if(!testTRIADRotation())
297 bool testTRIADRotation()
309 m = gsl_matrix_alloc(3,3);
329 const unsigned int NPTS=10;
331 std::random_device rd;
332 std::mt19937 gen(rd());
333 std::uniform_real_distribution<> distrib(0, 1);
335 std::vector<Point3D> pts,rotatedPts;
337 for(
auto ui=0;ui<NPTS;ui++)
339 pts[ui] =
Point3D(distrib(gen),
349 std::vector<float> weights;
350 weights.resize(pts.size(),1);
352 gsl_matrix *R=
nullptr;
356 for(
auto ui=0;ui<3;ui++)
358 for(
auto uj=0;uj<3;uj++)
362 TEST(TOL_EQ(gsl_matrix_get(R,ui,uj),1.0),
"Identity matrix");
366 TEST(TOL_EQ(gsl_matrix_get(R,ui,uj),0),
"Identity matrix (1)");
382 for(
auto &p : rotatedPts)
386 gsl_matrix *R_computed=
nullptr;
389 for(
auto ui=0u; ui<9;ui++)
391 ASSERT( TOL_EQ(R_computed->data[ui],R->data[ui]));
395 gsl_matrix_free(R_computed);
float sqrDist(const Point3D &pt) const
Returns the square of distance to another Point3D.
void computeRotationMatrix(const Point3D &ur1, const Point3D &ur2, const Point3D &r1, const Point3D &r2, gsl_matrix *m)
float gsl_determinant(const gsl_matrix *m)
unsigned int computeRotationMatrixWahba(const std::vector< Point3D > &unrotated, const std::vector< Point3D > &rotated, const std::vector< float > &weights, gsl_matrix *&R)
Given a series of paired observations of directions, compute the least squares rotation matrix betwee...
gsl_matrix * getRotationMatrix(const Point3D &pt, float theta)
Point3D crossProd(const Point3D &pt) const
Calculate the cross product of this and another point.
void gsl_matrix_mult(const gsl_matrix *A, const gsl_matrix *B, gsl_matrix *&res, bool alloc=false)
double gsl_matrix_det(gsl_matrix *A, bool inPlace=false)
float sqrMag() const
Returns magnitude^2, taking this as a position vector.
A 3D point data class storage.
void transform3x3(const gsl_matrix *matrix)
Perform a 3x3 matrix transformation using a GSL matrix.
void normalise()
Make point unit magnitude, maintaining direction.
void quat_rot(Point3D &p, const Point3D &r, float angle)
Rotate a point around a given rotation axis by a specified angle.