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 
   64 static void Jacobi4(
double **a, 
double *w, 
double **v)
 
   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 
  225 static void Perpendiculars(
const double x[3], 
double y[3], 
double z[3], 
double theta)
 
  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 AddToMat(Mat3d &matrix, const Mat3d &matrixToAdd)
static void Perpendiculars(const double x[3], double y[3], double z[3], double theta)
void MulVecTransposedVec(const Vec3d &vector1, const Vec3d &vector2, Mat3d &result)
void NormalizeVec(Vec3d &vec)
#define JACOBI_ROTATE(a, i, j, k, l)
static bool CalculateOptimalTransformation(const Vec3d *pSourcePoints, const Vec3d *pTargetPoints, int nPoints, Mat3d &rotation, Vec3d &translation)
void SubtractVecVec(const Vec3d &vector1, const Vec3d &vector2, Vec3d &result)
#define JACOBI_MAX_ROTATIONS
Data structure for the representation of a 3D vector. 
void MulMatVec(const Mat3d &matrix, const Vec3d &vec, Vec3d &result)
void SetMat(Mat3d &matrix, float r1, float r2, float r3, float r4, float r5, float r6, float r7, float r8, float r9)
static void Jacobi4(double **a, double *w, double **v)
void AddToVec(Vec3d &vec, const Vec3d &vectorToAdd)
Data structure for the representation of a 3x3 matrix. 
void MulVecScalar(const Vec3d &vec, float scalar, Vec3d &result)
void SetVec(Vec3d &vec, float x, float y, float z)