61 #define JACOBI_ROTATE(a, i, j, k, l) g = a[i][j]; h = a[k][l]; a[i][j] = g - s * (h + g * tau); a[k][l] = h + s * (g - h * tau) 62 #define JACOBI_MAX_ROTATIONS 20 70 for (i = 0; i < 4; i++)
72 for (j = 0; j < 4; j++)
77 b[i] = w[i] = a[i][i];
85 for (j = 0; j < 3; j++)
87 for (k = j + 1; k < 4; k++)
94 const double tresh = (i < 3) ? 0.2 * sum / 16 : 0;
96 for (j = 0; j < 3; j++)
98 for (k = j + 1; k < 4; k++)
100 double g = 100.0 * fabs(a[j][k]);
104 if (i > 3 && (fabs(w[j]) + g) == fabs(w[j]) && (fabs(w[k]) + g) == fabs(w[k]))
108 else if (fabs(a[j][k]) > tresh)
110 double h = w[k] - w[j];
112 if ((fabs(h) + g) == fabs(h))
118 theta = 0.5 * h / a[j][k];
119 t = 1.0 / (fabs(theta) + sqrt(1.0 + theta * theta));
125 double c = 1.0 / sqrt(1.0 + t * t);
127 double tau = s / (1.0 +
c);
136 for (l = 0; l < j; l++)
142 for (l = j + 1; l < k; l++)
148 for (l = k + 1; l < 4; l++)
153 for (l = 0; l < 4; l++)
161 for (j = 0; j < 4; j++)
170 for (j = 0; j < 3; j++)
176 for (i = j + 1; i < 4; i++)
190 for (i = 0; i < 4; i++)
201 const int nCeilHalf = (4 >> 1) + (4 & 1);
203 for (j = 0; j < 4; j++)
207 for (i = 0; i < 4; i++)
215 for(i = 0; i < 4; i++)
222 #undef JACOBI_MAX_ROTATIONS 227 const double x2 = x[0] * x[0];
228 const double y2 = x[1] * x[1];
229 const double z2 = x[2] * x[2];
230 const double r = sqrt(x2 + y2 + z2);
234 if (x2 > y2 && x2 > z2)
253 const double a = x[dx] /
r;
254 const double b = x[dy] /
r;
255 const double c = x[dz] /
r;
256 const double tmp = sqrt(a * a + c * c);
260 const double sintheta = sin(theta);
261 const double costheta = cos(theta);
265 y[dx] = (c * costheta - a * b * sintheta) / tmp;
266 y[dy] = sintheta * tmp;
267 y[dz] = (- a * costheta - b * c * sintheta) / tmp;
272 z[dx] = (-c * sintheta - a * b * costheta) / tmp;
273 z[dy] = costheta * tmp;
274 z[dz] = (a * sintheta - b * c * costheta) / tmp;
288 z[dx] = - a * b / tmp;
290 z[dz] = - b * c / tmp;
304 printf(
"error: CICP::CalculateOptimalTransformation needs at least two point pairs");
317 Vec3d source_centroid = { 0.0f, 0.0f, 0.0f };
318 Vec3d target_centroid = { 0.0f, 0.0f, 0.0f };
322 for (i = 0; i < nPoints; i++)
332 Mat3d M = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
334 for (i = 0; i < nPoints; i++)
348 double N0[4], N1[4], N2[4], N3[4];
349 double *N[4] = { N0, N1, N2, N3 };
351 for (i = 0; i < 4; i++)
361 N[0][0] = M.
r1 + M.
r5 + M.
r9;
362 N[1][1] = M.
r1 - M.
r5 - M.
r9;
363 N[2][2] = -M.
r1 + M.
r5 - M.
r9;
364 N[3][3] = -M.
r1 - M.
r5 + M.
r9;
367 N[0][1] = N[1][0] = M.
r6 - M.
r8;
368 N[0][2] = N[2][0] = M.
r7 - M.
r3;
369 N[0][3] = N[3][0] = M.
r2 - M.
r4;
371 N[1][2] = N[2][1] = M.
r2 + M.
r4;
372 N[1][3] = N[3][1] = M.
r7 + M.
r3;
373 N[2][3] = N[3][2] = M.
r6 + M.
r8;
375 double eigenvalues[4];
376 double eigenvectors0[4], eigenvectors1[4], eigenvectors2[4], eigenvectors3[4];
377 double *eigenvectors[4] = { eigenvectors0, eigenvectors1, eigenvectors2, eigenvectors3 };
380 Jacobi4(N, eigenvalues, eigenvectors);
388 if (eigenvalues[0] == eigenvalues[1] || nPoints == 2)
390 Vec3d s0, t0, s1, t1;
403 w = ds.
x * dt.
x + ds.
y * dt.
y + ds.
z * dt.
z;
404 x = ds.
y * dt.
z - ds.
z * dt.
y;
405 y = ds.
z * dt.
x - ds.
x * dt.
z;
406 z = ds.
x * dt.
y - ds.
y * dt.
x;
408 float r = sqrtf(x * x + y * y + z * z);
409 const float theta = atan2f(r, w);
412 w = cosf(0.5f * theta);
416 r = sinf(0.5f * theta) /
r;
424 double ds_[3] = { ds.
x, ds.
y, ds.
z };
429 r = sinf(0.5f * theta);
430 x = float(dt_[0] * r);
431 y = float(dt_[1] * r);
432 z = float(dt_[2] * r);
438 w = (float) eigenvectors[0][0];
439 x = (float) eigenvectors[1][0];
440 y = (float) eigenvectors[2][0];
441 z = (float) eigenvectors[3][0];
445 const float ww = w *
w;
446 const float wx = w *
x;
447 const float wy = w *
y;
448 const float wz = w *
z;
450 const float xx = x *
x;
451 const float yy = y *
y;
452 const float zz = z *
z;
454 const float xy = x *
y;
455 const float xz = x *
z;
456 const float yz = y *
z;
458 rotation.
r1 = ww + xx - yy - zz;
459 rotation.
r4 = 2.0f * (wz + xy);
460 rotation.
r7 = 2.0f * (-wy + xz);
462 rotation.
r2 = 2.0f * (-wz + xy);
463 rotation.
r5 = ww - xx + yy - zz;
464 rotation.
r8 = 2.0f * (wx + yz);
466 rotation.
r3 = 2.0f * (wy + xz);
467 rotation.
r6 = 2.0f * (-wx + yz);
468 rotation.
r9 = ww - xx - yy + zz;
void MulVecTransposedVec(const Vec3d &vector1, const Vec3d &vector2, Mat3d &result)
static void Perpendiculars(const double x[3], double y[3], double z[3], double theta)
void AddToMat(Mat3d &matrix, const Mat3d &matrixToAdd)
Data structure for the representation of a 3D vector.
static void Jacobi4(double **a, double *w, double **v)
#define JACOBI_MAX_ROTATIONS
void SetVec(Vec3d &vec, float x, float y, float z)
void MulVecScalar(const Vec3d &vec, float scalar, Vec3d &result)
void AddToVec(Vec3d &vec, const Vec3d &vectorToAdd)
static bool CalculateOptimalTransformation(const Vec3d *pSourcePoints, const Vec3d *pTargetPoints, int nPoints, Mat3d &rotation, Vec3d &translation)
void MulMatVec(const Mat3d &matrix, const Vec3d &vec, Vec3d &result)
#define JACOBI_ROTATE(a, i, j, k, l)
GLubyte GLubyte GLubyte a
GLdouble GLdouble GLdouble r
void NormalizeVec(Vec3d &vec)
void SubtractVecVec(const Vec3d &vector1, const Vec3d &vector2, Vec3d &result)
void SetMat(Mat3d &matrix, float r1, float r2, float r3, float r4, float r5, float r6, float r7, float r8, float r9)
Data structure for the representation of a 3x3 matrix.
GLubyte GLubyte GLubyte GLubyte w