3 #include "modules/perception/common/core/i_blas.h" 4 #include "modules/perception/common/core/i_rand.h" 5 #include "modules/perception/common/numeric/i_eig.h" 6 #include "modules/perception/common/numeric/i_svd.h" 23 T R[9],
int nr_svd_iter = I_DEFAULT_MAX_SVD_ITERATIONS) {
26 i_svd_3x3(R, Ut, w, Vt,
true, nr_svd_iter);
27 if (i_determinant_3x3(Ut) < (T)0.0) {
30 if (i_determinant_3x3(Vt) < (T)0.0) {
33 i_mult_AtB_3x3_3x3(Ut, Vt, R);
40 T a2_sqr,
const T a[3], T R[9]) {
42 R[0] = (T)1.0 - (a1_sqr + a2_sqr) * mcos;
43 R[4] = (T)1.0 - (a0_sqr + a2_sqr) * mcos;
44 R[8] = (T)1.0 - (a0_sqr + a1_sqr) * mcos;
45 tmp1 = a[0] * a[1] * mcos;
49 tmp1 = a[2] * a[0] * mcos;
53 tmp1 = a[1] * a[2] * mcos;
61 T a2_sqr,
const T s_da[3],
62 const T c_da[3],
const T a[3], T R[9],
64 T tmp1, tmp2, e_x[9], e_x2[9];
65 T mcos_x_a0 = mcos * a[0];
66 T mcos_x_a1 = mcos * a[1];
67 T mcos_x_a2 = mcos * a[2];
69 T mtwo_mcos_x_a0 = -(2 * mcos_x_a0);
70 T mtwo_mcos_x_a1 = -(2 * mcos_x_a1);
71 T mtwo_mcos_x_a2 = -(2 * mcos_x_a2);
73 R[0] = (T)1.0 - (a1_sqr + a2_sqr) * mcos;
74 R[4] = (T)1.0 - (a0_sqr + a2_sqr) * mcos;
75 R[8] = (T)1.0 - (a0_sqr + a1_sqr) * mcos;
77 tmp1 = a[0] * mcos_x_a1;
81 tmp1 = a[2] * mcos_x_a0;
85 tmp1 = a[1] * mcos_x_a2;
92 i_sqr_skew_symmetric_3x3(a, e_x2);
95 D[0][0] = (T)( e_x2[0] *
98 (T)( e_x2[0] * c_da[1] +
101 (T)( e_x2[0] * c_da[2] +
104 D[1][0] = (T)(e_x[1] * s_da[0] + e_x2[1] * c_da[0] +
106 D[1][1] = (T)(e_x[1] * s_da[1] + e_x2[1] * c_da[1] +
108 D[1][2] = (T)(e_x[1] * s_da[2] - sinc +
111 D[2][0] = (T)(e_x[2] * s_da[0] + e_x2[2] * c_da[0] +
113 D[2][1] = (T)(e_x[2] * s_da[1] + sinc +
115 D[2][2] = (T)(e_x[2] * s_da[2] + e_x2[2] * c_da[2] +
118 D[3][0] = (T)(e_x[3] * s_da[0] + e_x2[3] * c_da[0] +
120 D[3][1] = (T)(e_x[3] * s_da[1] + e_x2[3] * c_da[1] +
122 D[3][2] = (T)(e_x[3] * s_da[2] + sinc +
126 (T)( e_x2[4] * c_da[0] +
128 D[4][1] = (T)( e_x2[4] *
131 (T)( e_x2[4] * c_da[2] +
134 D[5][0] = (T)(e_x[5] * s_da[0] - sinc +
136 D[5][1] = (T)(e_x[5] * s_da[1] + e_x2[5] * c_da[1] +
138 D[5][2] = (T)(e_x[5] * s_da[2] + e_x2[5] * c_da[2] +
141 D[6][0] = (T)(e_x[6] * s_da[0] + e_x2[6] * c_da[0] +
143 D[6][1] = (T)(e_x[6] * s_da[1] - sinc +
145 D[6][2] = (T)(e_x[6] * s_da[2] + e_x2[6] * c_da[2] +
148 D[7][0] = (T)(e_x[7] * s_da[0] + sinc +
150 D[7][1] = (T)(e_x[7] * s_da[1] + e_x2[7] * c_da[1] +
152 D[7][2] = (T)(e_x[7] * s_da[2] + e_x2[7] * c_da[2] +
156 (T)( e_x2[8] * c_da[0] +
159 (T)( e_x2[8] * c_da[1] +
161 D[8][2] = (T)( e_x2[8] *
168 template <
typename T>
172 T a0_sqr = i_sqr(x[0]);
173 T a1_sqr = i_sqr(x[1]);
174 T a2_sqr = i_sqr(x[2]);
175 T theta2 = a0_sqr + a1_sqr + a2_sqr;
176 T theta = i_sqrt(theta2);
178 if (theta < Constant<T>::MIN_ABS_SAFE_DIVIDEND()) {
181 sinc = (T)1.0 - theta2 / (T)6.0;
182 mcos = (T)0.5 - theta2 / (T)24.0;
186 theta = (T)(1.0) - Constant<T>::TWO_PI() / theta;
188 a0_sqr = i_sqr(x[0]);
189 a1_sqr = i_sqr(x[1]);
190 a2_sqr = i_sqr(x[2]);
191 theta2 = a0_sqr + a1_sqr + a2_sqr;
192 theta = i_sqrt(theta2);
193 if (theta < Constant<T>::MIN_ABS_SAFE_DIVIDEND()) {
196 sinc = (T)1.0 - theta2 / (T)6.0;
197 mcos = (T)0.5 - theta2 / (T)24.0;
199 sinc = i_div(i_sin(theta), theta);
200 mcos = i_div((T)1.0 - i_cos(theta), theta2);
203 sinc = i_div(i_sin(theta), theta);
204 mcos = i_div((T)1.0 - i_cos(theta), theta2);
213 template <
typename T>
215 T sinc, mcos, x[3], s_da[3],
219 T a0_sqr = i_sqr(x[0]);
220 T a1_sqr = i_sqr(x[1]);
221 T a2_sqr = i_sqr(x[2]);
223 T theta2 = a0_sqr + a1_sqr + a2_sqr;
224 T theta = i_sqrt(theta2);
226 if (theta < Constant<T>::MIN_ABS_SAFE_DIVIDEND()) {
229 sinc = (T)1.0 - theta2 / (T)6.0;
230 mcos = (T)0.5 - theta2 / (T)24.0;
232 i_scale3(x, s_da, -i_rec((T)3.0));
233 i_scale3(x, c_da, -i_rec((T)12.0));
237 theta = (T)(1.0) - Constant<T>::TWO_PI() / theta;
239 a0_sqr = i_sqr(x[0]);
240 a1_sqr = i_sqr(x[1]);
241 a2_sqr = i_sqr(x[2]);
242 theta2 = a0_sqr + a1_sqr + a2_sqr;
243 theta = i_sqrt(theta2);
244 if (theta < Constant<T>::MIN_ABS_SAFE_DIVIDEND()) {
247 sinc = (T)1.0 - theta2 / (T)6.0;
248 mcos = (T)0.5 - theta2 / (T)24.0;
250 i_scale3(x, s_da, -i_rec((T)3.0));
251 i_scale3(x, c_da, -i_rec((T)12.0));
253 T sin_theta = i_sin(theta);
254 T cos_theta = i_cos(theta);
255 sinc = i_div(sin_theta, theta);
256 mcos = i_div((T)1.0 - cos_theta, theta2);
258 T s_dtheta = (cos_theta - sin_theta / theta) / theta2;
259 T c_dtheta = (sinc - (T)(2.0) * mcos) / theta2;
260 i_scale3(x, s_da, s_dtheta);
261 i_scale3(x, c_da, c_dtheta);
264 T sin_theta = i_sin(theta);
265 T cos_theta = i_cos(theta);
266 sinc = i_div(sin_theta, theta);
267 mcos = i_div((T)1.0 - cos_theta, theta2);
269 T s_dtheta = (cos_theta - sin_theta / theta) / theta2;
270 T c_dtheta = (sinc - (T)(2.0) * mcos) / theta2;
271 i_scale3(x, s_da, s_dtheta);
272 i_scale3(x, c_da, c_dtheta);
283 template <
typename T>
285 T sinc, mcos, tmp1, tmp2;
286 T a0_sqr = i_sqr(a[0]);
287 T a1_sqr = i_sqr(a[1]);
288 T a2_sqr = i_sqr(a[2]);
290 T theta2 = a0_sqr + a1_sqr + a2_sqr;
291 T theta = i_sqrt(theta2);
294 if (theta < Constant<T>::MIN_ABS_SAFE_DIVIDEND()) {
297 sinc = (T)1.0 - theta2 / (T)6.0;
298 mcos = (T)0.5 - theta2 / (T)24.0;
300 i_scale3(a, s_da, -i_rec((T)3.0));
301 i_scale3(a, c_da, -i_rec((T)12.0));
306 T sin_theta = i_sin(theta);
307 T cos_theta = i_cos(theta);
308 sinc = i_div(sin_theta, theta);
309 mcos = i_div((T)1.0 - cos_theta, theta2);
311 T s_dtheta = (cos_theta - sin_theta / theta) / theta2;
312 T c_dtheta = (sinc - (T)(2.0) * mcos) / theta2;
313 i_scale3(a, s_da, s_dtheta);
314 i_scale3(a, c_da, c_dtheta);
319 R[0] = (T)1.0 - (a1_sqr + a2_sqr) * mcos;
320 R[4] = (T)1.0 - (a0_sqr + a2_sqr) * mcos;
321 R[8] = (T)1.0 - (a0_sqr + a1_sqr) * mcos;
322 tmp1 = a[0] * a[1] * mcos;
326 tmp1 = a[2] * a[0] * mcos;
330 tmp1 = a[1] * a[2] * mcos;
339 static const T e_x_da[9][3] = {
340 {(T)0, (T)0, (T)0}, {(T)0, (T)0, -(T)1}, {(T)0, (T)1, (T)0},
341 {(T)0, (T)0, (T)1}, {(T)0, (T)0, (T)0}, {-(T)1, (T)0, (T)0},
342 {(T)0, -(T)1, (T)0}, {(T)1, (T)0, (T)0}, {(T)0, (T)0, (T)0}};
345 i_sqr_skew_symmetric_3x3(a, e_x2);
349 e_x2_da[0][0] = e_x2_da[1][2] = e_x2_da[2][1] = (T)0.0;
350 e_x2_da[3][2] = e_x2_da[4][1] = e_x2_da[5][0] = (T)0.0;
351 e_x2_da[6][1] = e_x2_da[7][0] = e_x2_da[8][2] = (T)0.0;
352 e_x2_da[1][1] = e_x2_da[3][1] = e_x2_da[2][2] = e_x2_da[6][2] = a[0];
353 e_x2_da[1][0] = e_x2_da[3][0] = e_x2_da[5][2] = e_x2_da[7][2] = a[1];
354 e_x2_da[2][0] = e_x2_da[6][0] = e_x2_da[5][1] = e_x2_da[7][1] = a[2];
355 e_x2_da[4][0] = e_x2_da[8][0] = -(T)2.0 * a[0];
356 e_x2_da[0][1] = e_x2_da[8][1] = -(T)2.0 * a[1];
357 e_x2_da[0][2] = e_x2_da[4][2] = -(T)2.0 * a[2];
368 D[0][0] = (T)(e_x[0] * s_da[0] + sinc * e_x_da[0][0] + e_x2[0] * c_da[0] +
369 mcos * e_x2_da[0][0]);
370 D[0][1] = (T)(e_x[0] * s_da[1] + sinc * e_x_da[0][1] + e_x2[0] * c_da[1] +
371 mcos * e_x2_da[0][1]);
372 D[0][2] = (T)(e_x[0] * s_da[2] + sinc * e_x_da[0][2] + e_x2[0] * c_da[2] +
373 mcos * e_x2_da[0][2]);
375 D[1][0] = (T)(e_x[1] * s_da[0] + sinc * e_x_da[1][0] + e_x2[1] * c_da[0] +
376 mcos * e_x2_da[1][0]);
377 D[1][1] = (T)(e_x[1] * s_da[1] + sinc * e_x_da[1][1] + e_x2[1] * c_da[1] +
378 mcos * e_x2_da[1][1]);
379 D[1][2] = (T)(e_x[1] * s_da[2] + sinc * e_x_da[1][2] + e_x2[1] * c_da[2] +
380 mcos * e_x2_da[1][2]);
382 D[2][0] = (T)(e_x[2] * s_da[0] + sinc * e_x_da[2][0] + e_x2[2] * c_da[0] +
383 mcos * e_x2_da[2][0]);
384 D[2][1] = (T)(e_x[2] * s_da[1] + sinc * e_x_da[2][1] + e_x2[2] * c_da[1] +
385 mcos * e_x2_da[2][1]);
386 D[2][2] = (T)(e_x[2] * s_da[2] + sinc * e_x_da[2][2] + e_x2[2] * c_da[2] +
387 mcos * e_x2_da[2][2]);
389 D[3][0] = (T)(e_x[3] * s_da[0] + sinc * e_x_da[3][0] + e_x2[3] * c_da[0] +
390 mcos * e_x2_da[3][0]);
391 D[3][1] = (T)(e_x[3] * s_da[1] + sinc * e_x_da[3][1] + e_x2[3] * c_da[1] +
392 mcos * e_x2_da[3][1]);
393 D[3][2] = (T)(e_x[3] * s_da[2] + sinc * e_x_da[3][2] + e_x2[3] * c_da[2] +
394 mcos * e_x2_da[3][2]);
396 D[4][0] = (T)(e_x[4] * s_da[0] + sinc * e_x_da[4][0] + e_x2[4] * c_da[0] +
397 mcos * e_x2_da[4][0]);
398 D[4][1] = (T)(e_x[4] * s_da[1] + sinc * e_x_da[4][1] + e_x2[4] * c_da[1] +
399 mcos * e_x2_da[4][1]);
400 D[4][2] = (T)(e_x[4] * s_da[2] + sinc * e_x_da[4][2] + e_x2[4] * c_da[2] +
401 mcos * e_x2_da[4][2]);
403 D[5][0] = (T)(e_x[5] * s_da[0] + sinc * e_x_da[5][0] + e_x2[5] * c_da[0] +
404 mcos * e_x2_da[5][0]);
405 D[5][1] = (T)(e_x[5] * s_da[1] + sinc * e_x_da[5][1] + e_x2[5] * c_da[1] +
406 mcos * e_x2_da[5][1]);
407 D[5][2] = (T)(e_x[5] * s_da[2] + sinc * e_x_da[5][2] + e_x2[5] * c_da[2] +
408 mcos * e_x2_da[5][2]);
410 D[6][0] = (T)(e_x[6] * s_da[0] + sinc * e_x_da[6][0] + e_x2[6] * c_da[0] +
411 mcos * e_x2_da[6][0]);
412 D[6][1] = (T)(e_x[6] * s_da[1] + sinc * e_x_da[6][1] + e_x2[6] * c_da[1] +
413 mcos * e_x2_da[6][1]);
414 D[6][2] = (T)(e_x[6] * s_da[2] + sinc * e_x_da[6][2] + e_x2[6] * c_da[2] +
415 mcos * e_x2_da[6][2]);
417 D[7][0] = (T)(e_x[7] * s_da[0] + sinc * e_x_da[7][0] + e_x2[7] * c_da[0] +
418 mcos * e_x2_da[7][0]);
419 D[7][1] = (T)(e_x[7] * s_da[1] + sinc * e_x_da[7][1] + e_x2[7] * c_da[1] +
420 mcos * e_x2_da[7][1]);
421 D[7][2] = (T)(e_x[7] * s_da[2] + sinc * e_x_da[7][2] + e_x2[7] * c_da[2] +
422 mcos * e_x2_da[7][2]);
424 D[8][0] = (T)(e_x[8] * s_da[0] + sinc * e_x_da[8][0] + e_x2[8] * c_da[0] +
425 mcos * e_x2_da[8][0]);
426 D[8][1] = (T)(e_x[8] * s_da[1] + sinc * e_x_da[8][1] + e_x2[8] * c_da[1] +
427 mcos * e_x2_da[8][1]);
428 D[8][2] = (T)(e_x[8] * s_da[2] + sinc * e_x_da[8][2] + e_x2[8] * c_da[2] +
429 mcos * e_x2_da[8][2]);
435 template <
typename T>
440 T Q[9], Ac[9], h[3], htA[3], ss[3];
443 T *Q_ref[3], *Ac_ref[3];
444 i_make_const_reference_3x3(R, R_ref);
445 i_make_reference_3x3(Q, Q_ref);
446 i_make_reference_3x3(Ac, Ac_ref);
449 i_eigenvector_from_eigenvalue(R_ref, (T)(1.0), Q_ref, h, htA, ss, Ac_ref, 3,
455 T c = (i_trace_3x3(R) - (T)1.0) *
458 T s = i_dot3(r, v) * (T)0.5;
459 theta = i_atan2(s, c);
467 template <
typename T>
468 inline bool i_rot_3x3(
const T a[3],
const T b[3], T R[9]) {
472 if (i_equal3(a, b)) {
480 if (s < Constant<T>::MIN_ABS_SAFE_DIVIDEND()) {
485 i_scale3(v, i_rec(s));
492 theta = i_acos(i_dot3(a, b));
520 template <
typename T>
522 T Q[9],
A[9], h[3], htA[3], ss[3];
523 T *R_ref[3], *Q_ref[3], *A_ref[3];
525 i_make_reference_3x3(R, R_ref);
526 i_make_reference_3x3(Q, Q_ref);
527 i_make_reference_3x3(A, A_ref);
528 i_rand_orthogonal<T>(Q_ref, A_ref, R_ref, h, htA, ss, 3, 3, iv, seed);
530 if (i_determinant_3x3(R) < (T)0.0) {
void i_rot_rodrigues_3x3_slow(const T a[3], T R[9], T D[9][3])
Definition: i_rot.h:284
void i_rot_rodrigues_3x3(const T a[3], T R[9])
Definition: i_rot.h:169
bool i_rot_3x3(const T a[3], const T b[3], T R[9])
Definition: i_rot.h:468
const size_t A
Definition: util.h:160
void i_rot_orthogonalize(T R[9], int nr_svd_iter=I_DEFAULT_MAX_SVD_ITERATIONS)
Definition: i_rot.h:22
const double PI
Definition: const_var.h:77
void i_force_rot_2x2(T R[4])
Definition: i_rot.h:13
void i_rand_rot_3x3(T R[9], int &seed, int force_proper=1)
Definition: i_rot.h:521
void i_rot_rodrigues_3x3_solver(T sinc, T mcos, T a0_sqr, T a1_sqr, T a2_sqr, const T a[3], T R[9])
Definition: i_rot.h:39
void i_rot_invert_rodrigues_3x3(const T R[9], T v[3], T &theta)
Definition: i_rot.h:436