absorient.cc
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:18k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. //############################################################
  2. // absorient.cc
  3. // Kari Pulli
  4. // 06/06/97
  5. // 
  6. // Two methods for solving the rotation and translation for
  7. // registering two sets of 3D points.
  8. //
  9. // Horn's method takes as input two lists of corresponding
  10. // 3D points. It calculates in one step the optimum motion
  11. // to align the sets. The starting point does not have to
  12. // be close to the solution.
  13. //
  14. // Chen & Medioni's method takes as input a list of points
  15. // and a list of planes, one plane for each point. The 
  16. // algorithm tries to move the sets so that the points get
  17. // close to their corresponding planes. It is assumed that
  18. // only small rotations are needed, i.e., the sets are 
  19. // in approximate registration.
  20. //############################################################
  21. #include <math.h>
  22. #include <limits.h>
  23. #include <iostream.h>
  24. #include "Pnt3.h"
  25. #include "Xform.h"
  26. #include "tnt.h"
  27. #include "vec.h"
  28. #include "cmat.h"
  29. #include "trislv.h"
  30. #include "transv.h"         /* transpose views */
  31. #include "lu.h"
  32. #include <float.h>
  33. #ifdef WIN32
  34. #define cbrt(r)  (pow((r), 1./3))
  35. #endif
  36. ////////////////////////////////////////////////////////
  37. ////////////////////////////////////////////////////////
  38. ////              Horn's method starts              ////
  39. ////////////////////////////////////////////////////////
  40. ////////////////////////////////////////////////////////
  41. // transform a quaternion to a rotation matrix
  42. static void 
  43. quaternion2matrix(double *q, double m[3][3])
  44. {
  45.   double q00 = q[0]*q[0];
  46.   double q11 = q[1]*q[1];
  47.   double q22 = q[2]*q[2];
  48.   double q33 = q[3]*q[3];
  49.   double q03 = q[0]*q[3];
  50.   double q13 = q[1]*q[3];
  51.   double q23 = q[2]*q[3];
  52.   double q02 = q[0]*q[2];
  53.   double q12 = q[1]*q[2];
  54.   double q01 = q[0]*q[1];
  55.   m[0][0] = q00 + q11 - q22 - q33;
  56.   m[1][1] = q00 - q11 + q22 - q33;
  57.   m[2][2] = q00 - q11 - q22 + q33;
  58.   m[0][1] = 2.0*(q12-q03);
  59.   m[1][0] = 2.0*(q12+q03);
  60.   m[0][2] = 2.0*(q13+q02);
  61.   m[2][0] = 2.0*(q13-q02);
  62.   m[1][2] = 2.0*(q23-q01);
  63.   m[2][1] = 2.0*(q23+q01);
  64. }
  65. // find the coefficients of the characteristic eqn.
  66. // l^4 + a l^3 + b l^2 + c l + d = 0
  67. // for a symmetric 4x4 matrix
  68. static void
  69. characteristicPol(double Q[4][4], double c[4])
  70. {
  71.   // squares
  72.   double q01_2 = Q[0][1] * Q[0][1];
  73.   double q02_2 = Q[0][2] * Q[0][2];
  74.   double q03_2 = Q[0][3] * Q[0][3];
  75.   double q12_2 = Q[1][2] * Q[1][2];
  76.   double q13_2 = Q[1][3] * Q[1][3];
  77.   double q23_2 = Q[2][3] * Q[2][3];
  78.   // other factors
  79.   double q0011 = Q[0][0] * Q[1][1];
  80.   double q0022 = Q[0][0] * Q[2][2];
  81.   double q0033 = Q[0][0] * Q[3][3];
  82.   double q0102 = Q[0][1] * Q[0][2];
  83.   double q0103 = Q[0][1] * Q[0][3];
  84.   double q0223 = Q[0][2] * Q[2][3];
  85.   double q1122 = Q[1][1] * Q[2][2];
  86.   double q1133 = Q[1][1] * Q[3][3];
  87.   double q1223 = Q[1][2] * Q[2][3];
  88.   double q2233 = Q[2][2] * Q[3][3];
  89.   // a
  90.   c[0] = -Q[0][0] - Q[1][1] - Q[2][2] - Q[3][3];
  91.   // b
  92.   c[1] = - q01_2 - q02_2 - q03_2 + q0011 - q12_2 - 
  93.     q13_2 + q0022 + q1122 - q23_2 + q0033 + q1133 + 
  94.     q2233;
  95.   // c
  96.   c[2] = (q02_2 + q03_2 + q23_2)*Q[1][1] - 2*q0102*Q[1][2] + 
  97.     (q12_2 + q13_2 + q23_2)*Q[0][0] +
  98.     (q01_2 + q03_2 - q0011 + q13_2 - q1133)*Q[2][2] - 
  99.     2*Q[0][3]*q0223 - 2*(q0103 + q1223)*Q[1][3] + 
  100.     (q01_2 + q02_2 - q0011 + q12_2 - q0022)*Q[3][3];
  101.     
  102.   // d
  103.   c[3] = 2*(-Q[0][2]*Q[0][3]*Q[1][2] + q0103*Q[2][2] -
  104.     Q[0][1]*q0223 + Q[0][0]*q1223)*Q[1][3] +
  105.     q02_2*q13_2 - q03_2*q1122 - q13_2*q0022 + 
  106.     2*Q[0][3]*Q[1][1]*q0223 - 2*q0103*q1223 + q01_2*q23_2 - 
  107.     q0011*q23_2 - q02_2*q1133 + q03_2*q12_2 +
  108.     2*q0102*Q[1][2]*Q[3][3] - q12_2*q0033 - q01_2*q2233 + 
  109.     q0011*q2233;
  110. }
  111. static int ferrari(double a, double b, double c, double d,
  112.   double rts[4]);
  113. // calculate the maximum eigenvector of a symmetric
  114. // 4x4 matrix
  115. // from B. Horn 1987 Closed-form solution of absolute
  116. // orientation using unit quaternions (J.Opt.Soc.Am.A)
  117. void
  118. maxEigenVector(double Q[4][4], double ev[4])
  119. {
  120.   static C_matrix<double> N(4,4);
  121.   double rts[4];
  122.   double c[4];
  123.   // find the coeffs for the characteristic eqn.
  124.   characteristicPol(Q, c);
  125.   // find roots
  126.   ferrari(c[0], c[1], c[2], c[3], rts);
  127.   // find maximum root = maximum eigenvalue
  128.   double l = rts[0];
  129.   if (rts[1] > l) l = rts[1];
  130.   if (rts[2] > l) l = rts[2];
  131.   if (rts[3] > l) l = rts[3];
  132.   /*
  133.   SHOW(l);
  134.   SHOW(rts[0]);
  135.   SHOW(rts[1]);
  136.   SHOW(rts[2]);
  137.   SHOW(rts[3]);
  138.   */
  139.   // create the Q - l*I matrix
  140.   N[0][0]=Q[0][0]-l;N[0][1]=Q[0][1] ;N[0][2]=Q[0][2]; N[0][3]=Q[0][3];
  141.   N[1][0]=Q[1][0]; N[1][1]=Q[1][1]-l;N[1][2]=Q[1][2]; N[1][3]=Q[1][3];
  142.   N[2][0]=Q[2][0]; N[2][1]=Q[2][1] ;N[2][2]=Q[2][2]-l;N[2][3]=Q[2][3];
  143.   N[3][0]=Q[3][0]; N[3][1]=Q[3][1] ;N[3][2]=Q[3][2];N[3][3]=Q[3][3]-l;
  144.   // the columns of the inverted matrix should be multiples of
  145.   // the eigenvector, pick the largest
  146.   static Vector<int> ipiv(4);
  147.   static Vector<double> best(4),curr(4);
  148.   //C_matrix<double> Ntmp = N;
  149.   if (LU_factor(N, ipiv)) {
  150.     //SHOW(Q[0][0]);
  151.     cerr << "maxEigenVector():" << endl;
  152.     cerr << "LU_factor failed!" << endl;
  153.     cerr << "return identity quaternion" << endl;
  154.     //cerr << N << endl;
  155.     ev[0] = 1.0;
  156.     ev[1] = ev[2] = ev[3] = 0.0;
  157.     return;
  158.   }
  159.   best = 0; best[0] = 1;
  160.   LU_solve(N, ipiv, best);
  161.   double len = 
  162.     best[0]*best[0] + best[1]*best[1] + 
  163.     best[2]*best[2] + best[3]*best[3];
  164.   for (int i=1; i<4; i++) {
  165.     curr = 0; curr[i] = 1;
  166.     LU_solve(N, ipiv, curr);
  167.     double tlen = 
  168.       curr[0]*curr[0] + curr[1]*curr[1] + 
  169.       curr[2]*curr[2] + curr[3]*curr[3];
  170.     if (tlen > len) { len = tlen; best = curr; }
  171.   }
  172.   // normalize the result
  173.   len = 1.0/sqrt(len);
  174.   ev[0] = best[0]*len;
  175.   ev[1] = best[1]*len;
  176.   ev[2] = best[2]*len;
  177.   ev[3] = best[3]*len;
  178. }
  179. // find the transformation that aligns measurements to
  180. // model
  181. void
  182. horn_align(Pnt3 *p,      // the model points  (source)
  183.    Pnt3 *x,      // the measured points (destination)
  184.    int n,        // how many pairs
  185.    double q[7])  // the reg. vector 0..3 rot, 4..6 trans
  186. {
  187.   if (n<3) {
  188.     cerr << "horn_align() was given " << n << " pairs," 
  189.  << " while at least 3 are required" << endl;
  190.     return;
  191.   }
  192.   Pnt3 p_mean, x_mean;
  193.   double S[3][3];
  194.   double Q[4][4];
  195.   int i,j;
  196.   // calculate the centers of mass
  197.   for (i=0; i<n; i++) {
  198.     p_mean += p[i];
  199.     x_mean += x[i];
  200.   }
  201.   p_mean /= n;
  202.   x_mean /= n;
  203.   // calculate the cross covariance matrix
  204.   for (i=0; i<3; i++)
  205.     for (j=0; j<3; j++)
  206.       S[i][j] = 0;
  207.   for (i=0; i<n; i++) {
  208.     S[0][0] += p[i][0]*x[i][0];
  209.     S[0][1] += p[i][0]*x[i][1];
  210.     S[0][2] += p[i][0]*x[i][2];
  211.     S[1][0] += p[i][1]*x[i][0];
  212.     S[1][1] += p[i][1]*x[i][1];
  213.     S[1][2] += p[i][1]*x[i][2];
  214.     S[2][0] += p[i][2]*x[i][0];
  215.     S[2][1] += p[i][2]*x[i][1];
  216.     S[2][2] += p[i][2]*x[i][2];
  217.   }
  218.   double fact = 1/double(n);
  219.   for (i=0; i<3; i++)
  220.     for (j=0; j<3; j++)
  221.       S[i][j] *= fact;
  222.   S[0][0] -= p_mean[0]*x_mean[0];
  223.   S[0][1] -= p_mean[0]*x_mean[1];
  224.   S[0][2] -= p_mean[0]*x_mean[2];
  225.   S[1][0] -= p_mean[1]*x_mean[0];
  226.   S[1][1] -= p_mean[1]*x_mean[1];
  227.   S[1][2] -= p_mean[1]*x_mean[2];
  228.   S[2][0] -= p_mean[2]*x_mean[0];
  229.   S[2][1] -= p_mean[2]*x_mean[1];
  230.   S[2][2] -= p_mean[2]*x_mean[2];
  231.   // calculate the 4x4 symmetric matrix Q
  232.   double trace = S[0][0] + S[1][1] + S[2][2];
  233.   double A23 = S[1][2] - S[2][1];
  234.   double A31 = S[2][0] - S[0][2];
  235.   double A12 = S[0][1] - S[1][0];
  236.   Q[0][0] = trace;
  237.   Q[0][1] = Q[1][0] = A23;
  238.   Q[0][2] = Q[2][0] = A31;
  239.   Q[0][3] = Q[3][0] = A12;
  240.   for (i=0; i<3; i++)
  241.     for (j=0; j<3; j++)
  242.       Q[i+1][j+1] = S[i][j]+S[j][i]-(i==j ? trace : 0);
  243.   
  244.   maxEigenVector(Q, q);
  245.   // calculate the rotation matrix
  246.   double m[3][3]; // rot matrix
  247.   quaternion2matrix(q, m);
  248.   // calculate the translation vector, put it into q[4..6]
  249.   q[4] = x_mean[0] - m[0][0]*p_mean[0] - 
  250.     m[0][1]*p_mean[1] - m[0][2]*p_mean[2];
  251.   q[5] = x_mean[1] - m[1][0]*p_mean[0] - 
  252.     m[1][1]*p_mean[1] - m[1][2]*p_mean[2];
  253.   q[6] = x_mean[2] - m[2][0]*p_mean[0] - 
  254.     m[2][1]*p_mean[1] - m[2][2]*p_mean[2];
  255. }
  256. /**************************************************/
  257. static int 
  258. qudrtc(double b, double c, double rts[4])
  259. /* 
  260.      solve the quadratic equation - 
  261.          x**2+b*x+c = 0 
  262. */
  263. {
  264.   int nquad;
  265.   double rtdis;
  266.   double dis = b*b-4.0*c;
  267.   
  268.   if (dis >= 0.0) {
  269.     nquad = 2;
  270.     rtdis = sqrt(dis);
  271.     if (b > 0.0) rts[0] = ( -b - rtdis)*.5;
  272.     else         rts[0] = ( -b + rtdis)*.5;
  273.     if (rts[0] == 0.0) rts[1] = -b;
  274.     else               rts[1] = c/rts[0];
  275.   } else {
  276.     nquad = 0;
  277.     rts[0] = 0.0;
  278.     rts[1] = 0.0;
  279.   }
  280.   return nquad;
  281. } /* qudrtc */
  282. /**************************************************/
  283. static double 
  284. cubic(double p, double q, double r)
  285. /* 
  286.      find the lowest real root of the cubic - 
  287.        x**3 + p*x**2 + q*x + r = 0 
  288.    input parameters - 
  289.      p,q,r - coeffs of cubic equation. 
  290.    output- 
  291.      cubic - a real root. 
  292.    method - 
  293.      see D.E. Littlewood, "A University Algebra" pp.173 - 6 
  294.      Charles Prineas   April 1981 
  295. */
  296. {
  297.   //int nrts;
  298.   double po3,po3sq,qo3;
  299.   double uo3,u2o3,uo3sq4,uo3cu4;
  300.   double v,vsq,wsq;
  301.   double m,mcube,n;
  302.   double muo3,s,scube,t,cosk,sinsqk;
  303.   double root;
  304.   
  305.   double doubmax = sqrt(DBL_MAX);
  306.   
  307.   m = 0.0;
  308.   //nrts =0;
  309.   if        ((p > doubmax) || (p <  -doubmax)) {
  310.     root = -p;
  311.   } else if ((q > doubmax) || (q <  -doubmax)) {
  312.     if (q > 0.0) root = -r/q;
  313.     else         root = -sqrt(-q);
  314.   } else if ((r > doubmax)|| (r <  -doubmax)) {
  315.     root =  -cbrt(r);
  316.   } else {
  317.     po3 = p/3.0;
  318.     po3sq = po3*po3;
  319.     if (po3sq > doubmax) root =  -p;
  320.     else {
  321.       v = r + po3*(po3sq + po3sq - q);
  322.       if ((v > doubmax) || (v < -doubmax)) 
  323. root = -p;
  324.       else {
  325. vsq = v*v;
  326. qo3 = q/3.0;
  327. uo3 = qo3 - po3sq;
  328. u2o3 = uo3 + uo3;
  329. if ((u2o3 > doubmax) || (u2o3 < -doubmax)) {
  330.   if (p == 0.0) {
  331.     if (q > 0.0) root =  -r/q;
  332.     else         root =  -sqrt(-q);
  333.   } else         root =  -q/p;
  334. }
  335. uo3sq4 = u2o3*u2o3;
  336. if (uo3sq4 > doubmax) {
  337.   if (p == 0.0) {
  338.     if (q > 0.0) root = -r/q;
  339.     else         root = -sqrt(fabs(q));
  340.   } else         root = -q/p;
  341. }
  342. uo3cu4 = uo3sq4*uo3;
  343. wsq = uo3cu4 + vsq;
  344. if (wsq >= 0.0) {
  345.   //
  346.   // cubic has one real root 
  347.   //
  348.   //nrts = 1;
  349.   if (v <= 0.0) mcube = ( -v + sqrt(wsq))*.5;
  350.   if (v  > 0.0) mcube = ( -v - sqrt(wsq))*.5;
  351.   m = cbrt(mcube);
  352.   if (m != 0.0) n = -uo3/m;
  353.   else          n = 0.0;
  354.   root = m + n - po3;
  355. } else {
  356.   //nrts = 3;
  357.   //
  358.   // cubic has three real roots 
  359.   //
  360.   if (uo3 < 0.0) {
  361.     muo3 = -uo3;
  362.     s = sqrt(muo3);
  363.     scube = s*muo3;
  364.     t =  -v/(scube+scube);
  365.     cosk = cos(acos(t)/3.0);
  366.     if (po3 < 0.0)
  367.       root = (s+s)*cosk - po3;
  368.     else {
  369.       sinsqk = 1.0 - cosk*cosk;
  370.       if (sinsqk < 0.0) sinsqk = 0.0;
  371.       root = s*( -cosk - sqrt(3*sinsqk)) - po3;
  372.     }
  373.   } else
  374.     //
  375.     // cubic has multiple root -  
  376.     //
  377.     root = cbrt(v) - po3;
  378. }
  379.       }
  380.     }
  381.   }
  382.   return root;
  383. } /* cubic */
  384. /***************************************/
  385. static int 
  386. ferrari(double a, double b, double c, double d, double rts[4])
  387. /* 
  388.      solve the quartic equation - 
  389.    x**4 + a*x**3 + b*x**2 + c*x + d = 0 
  390.      input - 
  391.    a,b,c,e - coeffs of equation. 
  392.      output - 
  393.    nquar - number of real roots. 
  394.    rts - array of root values. 
  395.      method :  Ferrari - Lagrange
  396.      Theory of Equations, H.W. Turnbull p. 140 (1947)
  397.      calls  cubic, qudrtc 
  398. */
  399. {
  400.   int nquar,n1,n2;
  401.   double asq,ainv2;
  402.   double v1[4],v2[4];
  403.   double p,q,r;
  404.   double y;
  405.   double e,f,esq,fsq,ef;
  406.   double g,gg,h,hh;
  407.   asq = a*a;
  408.   p = b;
  409.   q = a*c-4.0*d;
  410.   r = (asq - 4.0*b)*d + c*c;
  411.   y = cubic(p,q,r);
  412.   esq = .25*asq - b - y;
  413.   if (esq < 0.0) return(0);
  414.   else {
  415.     fsq = .25*y*y - d;
  416.     if (fsq < 0.0) return(0);
  417.     else {
  418.       ef = -(.25*a*y + .5*c);
  419.       if ( ((a > 0.0)&&(y > 0.0)&&(c > 0.0))
  420.    || ((a > 0.0)&&(y < 0.0)&&(c < 0.0))
  421.    || ((a < 0.0)&&(y > 0.0)&&(c < 0.0))
  422.    || ((a < 0.0)&&(y < 0.0)&&(c > 0.0))
  423.    ||  (a == 0.0)||(y == 0.0)||(c == 0.0)
  424.    ) {
  425. /* use ef - */
  426. if ((b < 0.0)&&(y < 0.0)&&(esq > 0.0)) {
  427.   e = sqrt(esq);
  428.   f = ef/e;
  429. } else if ((d < 0.0) && (fsq > 0.0)) {
  430.   f = sqrt(fsq);
  431.   e = ef/f;
  432. } else {
  433.   e = sqrt(esq);
  434.   f = sqrt(fsq);
  435.   if (ef < 0.0) f = -f;
  436. }
  437.       } else {
  438. e = sqrt(esq);
  439. f = sqrt(fsq);
  440. if (ef < 0.0) f = -f;
  441.       }
  442.       /* note that e >= 0.0 */
  443.       ainv2 = a*.5;
  444.       g = ainv2 - e;
  445.       gg = ainv2 + e;
  446.       if ( ((b > 0.0)&&(y > 0.0))
  447.    || ((b < 0.0)&&(y < 0.0)) ) {
  448. if (( a > 0.0) && (e != 0.0)) g = (b + y)/gg;
  449. else if (e != 0.0) gg = (b + y)/g;
  450.       }
  451.       if ((y == 0.0)&&(f == 0.0)) {
  452. h = 0.0;
  453. hh = 0.0;
  454.       } else if ( ((f > 0.0)&&(y < 0.0))
  455.   || ((f < 0.0)&&(y > 0.0)) ) {
  456. hh = -.5*y + f;
  457. h = d/hh;
  458.       } else {
  459. h = -.5*y - f;
  460. hh = d/h;
  461.       }
  462.       n1 = qudrtc(gg,hh,v1);
  463.       n2 = qudrtc(g,h,v2);
  464.       nquar = n1+n2;
  465.       rts[0] = v1[0];
  466.       rts[1] = v1[1];
  467.       rts[n1+0] = v2[0];
  468.       rts[n1+1] = v2[1];
  469.       return nquar;
  470.     }
  471.   }
  472. } /* ferrari */
  473. ////////////////////////////////////////////////////////
  474. ////////////////////////////////////////////////////////
  475. ////        Chen & Medioni's method starts          ////
  476. ////////////////////////////////////////////////////////
  477. ////////////////////////////////////////////////////////
  478. static void
  479. get_transform(double correction[6],
  480.       double m[3][3], double t[3])
  481. {
  482.   // produces a premult matrix: p' = M . p + t
  483.   double sa = sin(correction[0]); 
  484.   double ca = sqrt(1-sa*sa);
  485.   double sb = sin(correction[1]); 
  486.   double cb = sqrt(1-sb*sb);
  487.   double sr = sin(correction[2]);
  488.   double cr = sqrt(1-sr*sr);
  489.   t[0] = correction[3];
  490.   t[1] = correction[4];
  491.   t[2] = correction[5];
  492.   m[0][0] = cb*cr;
  493.   m[0][1] = -cb*sr;
  494.   m[0][2] = sb;
  495.   m[1][0] = sa*sb*cr + ca*sr;
  496.   m[1][1] = -sa*sb*sr + ca*cr;
  497.   m[1][2] = -sa*cb;
  498.   m[2][0] = -ca*sb*cr + sa*sr;
  499.   m[2][1] = ca*sb*sr + sa*cr;
  500.   m[2][2] = ca*cb;
  501. }
  502. // Solve x from Ax=b using Cholesky decomposition.
  503. // This function changes the contents of A in the process.
  504. static bool
  505. cholesky_solve(double A[6][6], double b[6], double x[6])
  506. {
  507.   int i, j, k;
  508.   double sum;
  509.   for (i=0; i<6; i++) {
  510.     for (sum=A[i][i], k=0; k<i; k++)
  511.       sum -= A[i][k]*A[i][k];
  512.       if (sum < 0.0) {
  513.         cerr << "Cholesky: matrix not pos.semidef." << endl;
  514.         SHOW(sum);
  515.         return false;
  516.       } else if (sum < 1.0e-7) {
  517.         cerr << "Cholesky: matrix not pos.def." << endl;
  518.         return false;
  519.       } else {
  520.         A[i][i] = sqrt(sum);
  521.     }
  522.     for (j=i+1; j<6; j++) {
  523.       for (sum=A[i][j], k=0; k<i; k++)
  524.         sum -= A[i][k]*A[j][k];
  525.       A[j][i] = sum / A[i][i];
  526.     }
  527.   }
  528.   for (i=0; i<6; i++) {               // Forward elimination;
  529.     for (sum=b[i], j=0; j<i; j++)     // solve Ly=b, store y in x
  530.       sum -= A[i][j]*x[j];
  531.     x[i] = sum / A[i][i];
  532.   }
  533.   for (i=5; i>=0; i--) {              // Backward elimination;
  534.     for (sum=x[i], j=i+1; j<6; j++)   // solve L'x = y
  535.       sum -= A[j][i]*x[j];
  536.     x[i] = sum / A[i][i];
  537.   }
  538.   return true;
  539. }
  540. // Calculate the rotation and translation that moves points in 
  541. // array ctr toward their pairs.
  542. void
  543. chen_medioni(Pnt3 *ctr,     // control points (source)
  544.      Pnt3 *srf,     // points on the tangent plane (target)
  545.      Pnt3 *nrm,     // the normals at the pairs
  546.      int n,         // how many pairs
  547.      double q[7])   // registration quaternion
  548. {
  549.   // The least-squares solutions for the translation and 
  550.   // rotation are found independently.
  551.   // Therefore it is much better to first move the control points
  552.   // around origin, and fix the result in the end.
  553.   // cm = Sum{ctr[i]}/n
  554.   // R(p-cm) + t + cm == Rp + { t + cm - Rcm }
  555.   
  556.   Pnt3 cm;
  557.   for (int i=0; i<n; i++) cm += ctr[i];
  558.   cm /= float(n);
  559.   double HtH[6][6];
  560.   double HtP[6], Hi[6];
  561.   for (i=0; i<6; i++) {
  562.     HtH[i][0] =
  563.     HtH[i][1] =
  564.     HtH[i][2] =
  565.     HtH[i][3] =
  566.     HtH[i][4] =
  567.     HtH[i][5] =
  568.     HtP[i] = 0;
  569.   }
  570.   double Pi;
  571.   Pnt3 PxS;
  572.   double sum = 0;
  573.   for (i=0; i<n; i++) {
  574.     Pi = dot(srf[i]-ctr[i], nrm[i]);
  575.     PxS = cross(ctr[i]-cm, nrm[i]);
  576.     Hi[0] = PxS[0];
  577.     Hi[1] = PxS[1];
  578.     Hi[2] = PxS[2];
  579.     Hi[3] = nrm[i][0];
  580.     Hi[4] = nrm[i][1];
  581.     Hi[5] = nrm[i][2];
  582.     HtP[0] += Pi * Hi[0];
  583.     HtP[1] += Pi * Hi[1];
  584.     HtP[2] += Pi * Hi[2];
  585.     HtP[3] += Pi * Hi[3];
  586.     HtP[4] += Pi * Hi[4];
  587.     HtP[5] += Pi * Hi[5];
  588.     HtH[0][0] += Hi[0]*Hi[0];
  589.     HtH[0][1] += Hi[0]*Hi[1];
  590.     HtH[0][2] += Hi[0]*Hi[2];
  591.     HtH[0][3] += Hi[0]*Hi[3];
  592.     HtH[0][4] += Hi[0]*Hi[4];
  593.     HtH[0][5] += Hi[0]*Hi[5];
  594.     HtH[1][1] += Hi[1]*Hi[1];
  595.     HtH[1][2] += Hi[1]*Hi[2];
  596.     HtH[1][3] += Hi[1]*Hi[3];
  597.     HtH[1][4] += Hi[1]*Hi[4];
  598.     HtH[1][5] += Hi[1]*Hi[5];
  599.     HtH[2][2] += Hi[2]*Hi[2];
  600.     HtH[2][3] += Hi[2]*Hi[3];
  601.     HtH[2][4] += Hi[2]*Hi[4];
  602.     HtH[2][5] += Hi[2]*Hi[5];
  603.     HtH[3][3] += Hi[3]*Hi[3];
  604.     HtH[3][4] += Hi[3]*Hi[4];
  605.     HtH[3][5] += Hi[3]*Hi[5];
  606.     HtH[4][4] += Hi[4]*Hi[4];
  607.     HtH[4][5] += Hi[4]*Hi[5];
  608.     HtH[5][5] += Hi[5]*Hi[5];
  609.     sum += Pi*Pi;
  610.   }
  611.   cout << "Sqrt of average squared error before transform " 
  612.        << sqrtf(sum/n) << endl;
  613.   
  614.   // solve Ax=b using Cholesky decomposition
  615.   double d[6];
  616.   Xform<double> xf;
  617.   if( cholesky_solve(HtH,HtP,d) ) {
  618.     double m[3][3];
  619.     double t[3];
  620.     get_transform(d, m, t);
  621.     
  622.     // fix the translation, see comments above
  623.     float *c = &cm[0];
  624.     t[0] += c[0] - (m[0][0]*c[0]+m[0][1]*c[1]+m[0][2]*c[2]);
  625.     t[1] += c[1] - (m[1][0]*c[0]+m[1][1]*c[1]+m[1][2]*c[2]);
  626.     t[2] += c[2] - (m[2][0]*c[0]+m[2][1]*c[1]+m[2][2]*c[2]);
  627.     // output as quaternion
  628.     xf.fromRotTrans (m, t);
  629.   } else {
  630.     cerr << "Warning: Cholesky failed" << endl;
  631.   }
  632.   xf.toQuaternion (q);
  633.   xf.getTranslation (q+4);
  634. }
  635. #ifdef TEST_ABSORIENT
  636. #include "Pnt3.h"
  637. #include "Random.h"
  638. #include "Xform.h"
  639. void
  640. main(void)
  641. {
  642.   Random rand;
  643.   Pnt3 x[1000];
  644.   Pnt3 p[1000];
  645.   double qd[7];
  646.   // random points
  647.   for (int i=0; i<1000; i++) {
  648.     x[i] = Pnt3(rand(), rand(), rand())*200.0 - Pnt3(100,100,100);
  649.   }
  650.   // random rotation
  651.   double axis[3] = {1,1,1};
  652.   axis[0] = rand();
  653.   axis[1] = rand();
  654.   axis[2] = rand();
  655.   Xform<double> xf;
  656.   xf.rot(rand(), axis[0], axis[1], axis[2]);
  657.   float sum = 0.0;
  658.   for (i=0; i<1000; i++) {
  659.     p[i] = x[i];
  660.     xf(p[i]);
  661.     sum += dist2(p[i],x[i]);
  662.   }
  663.   SHOW(sum);
  664.   horn_align(&p[0], &x[0], 1000, qd);
  665.   xf.fromQuaternion(qd, qd[4], qd[5], qd[6]);
  666.   sum = 0.0;
  667.   for (i=0; i<1000; i++) {
  668.     xf(p[i]);
  669.     sum += dist2(p[i],x[i]);
  670.   }
  671.   SHOW(sum);
  672. }
  673. #endif