Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 4627 in orxonox.OLD for orxonox/trunk/src/lib/collision_detection


Ignore:
Timestamp:
Jun 14, 2005, 1:39:31 AM (19 years ago)
Author:
patrick
Message:

orxonox/trunk: trying to implement my own jacobi decomposition alg since the other once didn't work… shit

Location:
orxonox/trunk/src/lib/collision_detection
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • orxonox/trunk/src/lib/collision_detection/Makefile.am

    r4547 r4627  
    2525                     bv_tree_node.h \
    2626                     bounding_volume.h \
    27                      bounding_sphere.h
     27                     bounding_sphere.h \
     28                     lin_alg.h
    2829
  • orxonox/trunk/src/lib/collision_detection/Makefile.in

    r4547 r4627  
    208208                     bv_tree_node.h \
    209209                     bounding_volume.h \
    210                      bounding_sphere.h
     210                     bounding_sphere.h \
     211                     lin_alg.h
    211212
    212213all: all-am
  • orxonox/trunk/src/lib/collision_detection/lin_alg.h

    r4626 r4627  
     1/*!
     2    \file lin_alg.h
     3    \brief Definition of some important linear algebra formulas
     4
     5    compute the eigenpairs (eigenvalues and eigenvectors) of a real symmetric matrix "A" by the Jacobi method
     6 */
     7
     8#include "abstract_model.h"
     9
     10#include <stdio.h>
     11#include <math.h>
     12
     13#define NDIM 3
     14
     15
     16typedef float MatrixX[3][3];
     17
     18//
     19// class "EVJacobi" for computing the eigenpairs
     20// (members)
     21//   ndim  int    ...  dimension
     22//       "ndim" must satisfy 1 < ndim < NDIM
     23//   ("NDIM" is given above).
     24//   a     double [NDIM][NDIM] ...  matrix A
     25//   aa    double ...  the square root of
     26//                  (1/2) x (the sum of the off-diagonal elements squared)
     27//   ev    double [NDIM] ...  eigenvalues
     28//   evec  double [NDIM][NDIM] ... eigenvectors
     29//       evec[i][k], i=1,2,...,ndim are the elements of the eigenvector
     30//       corresponding to the k-th eigenvalue ev[k]
     31//   vec   double [NDIM][NDIM] ... the 2-dimensional array where the matrix elements are stored
     32//   lSort     int      ...
     33//       If lSort = 1, sort the eigenvalues d(i) in the descending order, i.e.,
     34//                       ev[1] >= ev[2] >= ... >= ev[ndim], and
     35//       if lSort = 0, in the ascending order, i.e.,
     36//                       ev[1] <= ev[2] <= ... <= ev[ndim].
     37//   lMatSize  int      ...  If 1 < ndim < NDIM, lMatSize = 1
     38//                            otherwise, lMatSize = 0
     39//   p     int [NDIM]    ...  index vector for sorting the eigenvalues
     40// (public member functions)
     41//   setMatrix          void ...  give the matrix A
     42//   getEigenValue      void ...  get the eigenvalues
     43//   getEigenVector     void ...  get the eigenvectors
     44//   sortEigenpair      void ...  sort the eigenpairs
     45// (private member functions)
     46//   ComputeEigenpair   void ...  compute the eigenpairs
     47//   matrixUpdate       void ...  each step of the Jacobi method, i.e.,
     48//                          update of the matrix A by Givens' transform.
     49//   getP               void ...  get the index vector p, i.e., sort the eigenvalues.
     50//   printMatrix        void ...  print the elements of the matrix A.
     51//
     52
     53class EVJacobi
     54{
     55  public:
     56    void setMatrix(int, double [][NDIM], int, int);
     57    void getEigenValue(double []);
     58    void getEigenVector(double [][NDIM]);
     59    void sortEigenpair(int);
     60
     61  private:
     62    void ComputeEigenpair(int);
     63    void matrixUpdate(void);
     64    void getP(void);
     65    void printMatrix(void);
     66
     67  private:
     68    double a[NDIM][NDIM], aa, ev[NDIM], evec[NDIM][NDIM], vec[NDIM][NDIM];
     69    int ndim, lSort, p[NDIM], lMatSize;
     70};
     71
     72//------------public member function of the class "EVJacobi"------------------------------
     73//
     74// give the dimension "ndim" and the matrix "A" and compute the eigenpairs
     75// (input)
     76// ndim0    int      ... dimension
     77// a0     double[][NDIM]  matrix A
     78// lSort0  int      ... lSort
     79//       If lSort = 1, sort the eigenvalues d(i) in the descending order, i.e.,
     80//                       ev[1] >= ev[2] >= ... >= ev[ndim], and
     81//       if lSort = 0, in the ascending order, i.e.,
     82//                       ev[1] <= ev[2] <= ... <= ev[ndim].
     83// l_print  int      ...
     84//       If l_print = 1, print the matrices during the iterations.
     85//
     86void EVJacobi::setMatrix(int ndim0, double a0[][NDIM], int lSort0, int l_print)
     87{
     88  ndim = ndim0;
     89  if (ndim < NDIM && ndim > 1)
     90  {
     91    lMatSize = 1;
     92    lSort = lSort0;
     93    for (int i=1; i<=ndim; ++i)
     94      for (int j=1; j<=ndim; ++j)
     95        a[i][j] = a0[i][j];
     96    //
     97    aa = 0.0;
     98    for (int i=1; i<=ndim; ++i)
     99      for (int j=1; j<=i-1; ++j)
     100        aa += a[i][j]*a[i][j];
     101    aa = sqrt(aa);
     102    //
     103    ComputeEigenpair(l_print);
     104    getP();
     105  }
     106  else
     107  {
     108    lMatSize = 0;
     109    printf("ndim = %d\n", ndim);
     110    printf("ndim must satisfy 1 < ndim < NDIM=%d\n", NDIM);
     111  }
     112}
     113//
     114// get the eigenvalues
     115// (input)
     116// ev0[NDIM] double ...  the array where the eigenvalues are written
     117void EVJacobi::getEigenValue(double ev0[])
     118{
     119  for (int k=1; k<=ndim; ++k) ev0[k] = ev[p[k]];
     120}
     121//
     122// get the eigenvectors
     123// (input)
     124// evec0[NDIM][NDIM] double ...  the two-dimensional array
     125//   where the eigenvectors are written in such a way that
     126//   evec0[k][i], i=1,2,...,ndim are the elements of the eigenvector
     127//   corresponding to the k-th eigenvalue ev0[k]
     128//
     129void EVJacobi::getEigenVector(double evec0[][NDIM])
     130{
     131  for (int k=1; k<=ndim; ++k)
     132    for (int i=1; i<=ndim; ++i)
     133      evec0[k][i] = evec[p[k]][i];
     134}
     135//
     136// sort the eigenpairs
     137// (input)
     138// lSort0  int
     139//   If lSort0 = 1, the eigenvalues are sorted in the descending order, i.e.,
     140//      ev0[1] >= ev0[2] >= ... >= ev0[ndim]
     141//   and if lSort0 = 0, in the ascending order, i.e.,
     142//      ev0[1] <= ev0[2] <= ... <= ev0[ndim]
     143//
     144void EVJacobi::sortEigenpair(int lSort0)
     145{
     146  lSort = lSort0;
     147  getP();
     148}
     149//-------private member function of the class "EVJacobi"-----
     150//
     151// compute the eigenpairs
     152// (input)
     153// l_print  int
     154//    If l_print = 1, print the matrices during the iterations.
     155//
     156void EVJacobi::ComputeEigenpair(int l_print)
     157{
     158  if (lMatSize==1)
     159  {
     160    if (l_print==1)
     161    {
     162      printf("step %d\n", 0);
     163      printMatrix();
     164      printf("\n");
     165    }
     166    //
     167    double eps = 1.0e-15, epsa = eps * aa;
     168    int kend = 1000, l_conv = 0;
     169    //
     170    for (int i=1; i<=ndim; ++i)
     171      for (int j=1; j<=ndim; ++j)
     172        vec[i][j] = 0.0;
     173    for (int i=1; i<=ndim; ++i)
     174      vec[i][i] = 1.0;
     175    //
     176    for (int k=1; k<=kend; ++k)
     177    {
     178      matrixUpdate();
     179      double a1 = 0.0;
     180      for (int i=1; i<=ndim; ++i)
     181        for (int j=1; j<=i-1; ++j)
     182          a1 += a[i][j] * a[i][j];
     183      a1 = sqrt(a1);
     184      if (a1 < epsa)
     185      {
     186        if (l_print==1)
     187        {
     188          printf("converged at step %d\n", k);
     189          printMatrix();
     190          printf("\n");
     191        }
     192        l_conv = 1;
     193        break;
     194      }
     195      if (l_print==1)
     196        if (k%10==0)
     197      {
     198        printf("step %d\n", k);
     199        printMatrix();
     200        printf("\n");
     201      }
     202    }
     203    //
     204    if (l_conv == 0) printf("Jacobi method not converged.\n");
     205    for (int k=1; k<=ndim; ++k)
     206    {
     207      ev[k] = a[k][k];
     208      for (int i=1; i<=ndim; ++i) evec[k][i] = vec[i][k];
     209    }
     210  }
     211}
     212//
     213void EVJacobi::printMatrix(void)
     214{
     215  for (int i=1; i<=ndim; ++i)
     216  {
     217    for (int j=1; j<=ndim; ++j) printf("%8.1e ",a[i][j]);
     218    printf("\n");
     219  }
     220}
     221//
     222void EVJacobi::matrixUpdate(void)
     223{
     224  double a_new[NDIM][NDIM], vec_new[NDIM][NDIM];
     225  //
     226  int p=2, q=1;
     227  double amax = fabs(a[p][q]);
     228  for (int i=3; i<=ndim; ++i)
     229    for (int j=1; j<=i-1; ++j)
     230      if (fabs(a[i][j]) > amax)
     231  {
     232    p = i;
     233    q = j;
     234    amax = fabs(a[i][j]);
     235  }
     236  //
     237        // Givens' rotation by Rutishauser's rule
     238  //
     239  double z, t, c, s, u;
     240  z = (a[q][q]  - a[p][p]) / (2.0 * a[p][q]);
     241  t = fabs(z) + sqrt(1.0 + z*z);
     242  if (z < 0.0) t = - t;
     243  t = 1.0 / t;
     244  c = 1.0 / sqrt(1.0 + t*t);
     245  s = c * t;
     246  u = s / (1.0 + c);
     247  //
     248  for (int i=1; i<=ndim; ++i)
     249    for (int j=1; j<=ndim; ++j)
     250      a_new[i][j] = a[i][j];
     251  //
     252  a_new[p][p] = a[p][p] - t * a[p][q];
     253  a_new[q][q] = a[q][q] + t * a[p][q];
     254  a_new[p][q] = 0.0;
     255  a_new[q][p] = 0.0;
     256  for (int j=1; j<=ndim; ++j)
     257    if (j!=p && j!=q)
     258  {
     259    a_new[p][j] = a[p][j] - s * (a[q][j] + u * a[p][j]);
     260    a_new[j][p] = a_new[p][j];
     261    a_new[q][j] = a[q][j] + s * (a[p][j] - u * a[q][j]);
     262    a_new[j][q] = a_new[q][j];
     263  }
     264  //
     265  for (int i=1; i<=ndim; ++i)
     266  {
     267    vec_new[i][p] = vec[i][p] * c - vec[i][q] * s;
     268    vec_new[i][q] = vec[i][p] * s + vec[i][q] * c;
     269    for (int j=1; j<=ndim; ++j)
     270      if (j!=p && j!=q) vec_new[i][j] = vec[i][j];
     271  }
     272  //
     273  for (int i=1; i<=ndim; ++i)
     274    for (int j=1; j<=ndim; ++j)
     275  {
     276    a[i][j] = a_new[i][j];
     277    vec[i][j] = vec_new[i][j];
     278  }
     279}
     280//
     281// sort the eigenpairs
     282//   If l_print=1, sort the eigenvalues in the descending order, i.e.,
     283//      ev[1] >= ev[2] >= ... >= ev[ndim], and
     284//   if l_print=0, in the ascending order, i.e.,
     285//      ev[1] <= ev[2] <= ... <= ev[ndim].
     286//
     287void EVJacobi::getP(void)
     288{
     289  for (int i=1; i<=ndim; ++i) p[i] = i;
     290  //
     291  if (lSort==1)
     292  {
     293    for (int k=1; k<=ndim; ++k)
     294    {
     295      double emax = ev[p[k]];
     296      for (int i=k+1; i<=ndim; ++i)
     297      {
     298        if (emax < ev[p[i]])
     299        {
     300          emax = ev[p[i]];
     301          int pp = p[k];
     302          p[k] = p[i];
     303          p[i] = pp;
     304        }
     305      }
     306    }
     307  }
     308  if (lSort==0)
     309  {
     310    for (int k=1; k<=ndim; ++k)
     311    {
     312      double emin = ev[p[k]];
     313      for (int i=k+1; i<=ndim; ++i)
     314      {
     315        if (emin > ev[p[i]])
     316        {
     317          emin = ev[p[i]];
     318          int pp = p[k];
     319          p[k] = p[i];
     320          p[i] = pp;
     321        }
     322      }
     323    }
     324  }
     325}
     326
     327
     328
     329
     330
     331
     332
     333//  void jacobi(Matrix A, int n, sVec3D d, Matrix V, int *nRot)
     334// {
     335//   sVec3D  B, Z;
     336//   double  c, g, h, s, sm, t, tau, theta, tresh;
     337//   int     i, j, ip, iq;
     338//
     339//   void *vmblock1 = NULL;
     340//
     341//   //allocate vectors B, Z
     342//   vmblock1 = vminit();
     343//   //B = (REAL *) vmalloc(vmblock1, VEKTOR,  100, 0);
     344//   //Z = (REAL *) vmalloc(vmblock1, VEKTOR,  100, 0);
     345//
     346//    //initialize V to identity matrix
     347//   for(int i = 1; i <= n; i++)
     348//   {
     349//     for(int j = 1; j <= n; j++)
     350//         V[i][j] = 0;
     351//     V[i][i] = 1;
     352//   }
     353//
     354//   for(int i = 1; i <= n; i++)
     355//   {
     356//     B[i] = A[i][i];
     357//     D[i] = B[i];
     358//     Z[i] = 0;
     359//   }
     360//
     361//   *nRot = 0;
     362//   for(int i = 1; i<=50; i++)
     363//   {
     364//     sm = 0;
     365//     for(int k = 1; k < n; k++)    //sum off-diagonal elements
     366//       for (int l = k + 1; l <= n; k++)
     367//         sm = sm + fabs(A[k][l]);
     368//     if ( sm == 0 )
     369//     {
     370//       //vmfree(vmblock1);
     371//       return;       //normal return
     372//     }
     373//     if (i < 4)
     374//       tresh = 0.2 * sm * sm;
     375//     else
     376//       tresh = 0;
     377//     for(int k = 1; k < n; k++)
     378//     {
     379//       for (iq=ip+1; iq<=N; iq++) {
     380//         g=100*fabs(A[ip][iq]);
     381// // after 4 sweeps, skip the rotation if the off-diagonal element is small
     382//         if ((i > 4) && (fabs(D[ip])+g == fabs(D[ip])) && (fabs(D[iq])+g == fabs(D[iq])))
     383//           A[ip][iq]=0;
     384//         else if (fabs(A[ip][iq]) > tresh) {
     385//           h=D[iq]-D[ip];
     386//           if (fabs(h)+g == fabs(h))
     387//             t=A[ip][iq]/h;
     388//           else {
     389//             theta=0.5*h/A[ip][iq];
     390//             t=1/(fabs(theta)+sqrt(1.0+theta*theta));
     391//             if (theta < 0)  t=-t;
     392//           }
     393//           c=1.0/sqrt(1.0+t*t);
     394//           s=t*c;
     395//           tau=s/(1.0+c);
     396//           h=t*A[ip][iq];
     397//           Z[ip] -= h;
     398//           Z[iq] += h;
     399//           D[ip] -= h;
     400//           D[iq] += h;
     401//           A[ip][iq]=0;
     402//           for (j=1; j<ip; j++) {
     403//             g=A[j][ip];
     404//             h=A[j][iq];
     405//             A[j][ip] = g-s*(h+g*tau);
     406//             A[j][iq] = h+s*(g-h*tau);
     407//           }
     408//           for (j=ip+1; j<iq; j++) {
     409//             g=A[ip][j];
     410//             h=A[j][iq];
     411//             A[ip][j] = g-s*(h+g*tau);
     412//             A[j][iq] = h+s*(g-h*tau);
     413//           }
     414//           for (j=iq+1; j<=N; j++) {
     415//             g=A[ip][j];
     416//             h=A[iq][j];
     417//             A[ip][j] = g-s*(h+g*tau);
     418//             A[iq][j] = h+s*(g-h*tau);
     419//           }
     420//           for (j=1; j<=N; j++) {
     421//             g=V[j][ip];
     422//             h=V[j][iq];
     423//             V[j][ip] = g-s*(h+g*tau);
     424//             V[j][iq] = h+s*(g-h*tau);
     425//           }
     426//           *NROT=*NROT+1;
     427//         } //end ((i.gt.4)...else if
     428//       } // main iq loop
     429//     } // main ip loop
     430//     for (ip=1; ip<=N; ip++) {
     431//       B[ip] += Z[ip];
     432//       D[ip]=B[ip];
     433//       Z[ip]=0;
     434//     }
     435//   } //end of main i loop
     436//   printf("\n 50 iterations !\n");
     437//   vmfree(vmblock1);
     438//   return;  //too many iterations
     439// }
     440
  • orxonox/trunk/src/lib/collision_detection/obb_tree_node.cc

    r4626 r4627  
    3636#include "newmatio.h"
    3737
     38#include "lin_alg.h"
     39
    3840
    3941
     
    101103  Vector    p, q, r;                                 //!< holder of the polygon data, much more conveniant to work with Vector than sVec3d
    102104  Vector    t1, t2;                                  //!< temporary values
    103   float     covariance[3][3];                        //!< the covariance matrix
     105  double    covariance[3][3];                        //!< the covariance matrix
    104106
    105107  this->numOfVertices = length;
     
    191193  Vector**              axis = new Vector*[3];                //!< the references to the obb axis
    192194
    193   C(1,1) = covariance[0][0];
    194   C(1,2) = covariance[0][1];
    195   C(1,3) = covariance[0][2];
    196   C(2,1) = covariance[1][0];
    197   C(2,2) = covariance[1][1];
    198   C(2,3) = covariance[1][2];
    199   C(3,1) = covariance[2][0];
    200   C(3,2) = covariance[2][1];
    201   C(3,3) = covariance[2][2];
     195
     196  double a[4][4];
     197
     198  a[0][0] = C(1,1) = covariance[0][0];
     199  a[0][1] = C(1,2) = covariance[0][1];
     200  a[0][2] = C(1,3) = covariance[0][2];
     201  a[1][0] = C(2,1) = covariance[1][0];
     202  a[1][1] = C(2,2) = covariance[1][1];
     203  a[1][2] = C(2,3) = covariance[1][2];
     204  a[2][0] = C(3,1) = covariance[2][0];
     205  a[2][1] = C(3,2) = covariance[2][1];
     206  a[2][2] = C(3,3) = covariance[2][2];
    202207
    203208  Jacobi(C, D, V);                                            /* do the jacobi decomposition */
    204209  PRINTF(0)("-- Done Jacobi Decomposition\n");
    205210
    206 //   printf("\nwe got a result! YES: \n");
    207 //
    208 //   for(int j = 1; j < 4; ++j)
    209 //   {
    210 //     printf(" |");
    211 //     for(int k = 1; k < 4; ++k)
    212 //     {
    213 //       printf(" \b%f ", V(j, k));
    214 //     }
    215 //     printf(" |\n");
    216 //   }
     211
     212  /* new jacobi tests */
     213  double eigenvectors[3][3];
     214  double eigval[3];
     215
     216  EVJacobi jac;
     217  jac.setMatrix(2, covariance, 0, 0);
     218  jac.getEigenVector(eigenvectors);
     219
     220
     221  printf("Old Jacobi\n");
     222  for(int j = 1; j < 4; ++j)
     223  {
     224    printf(" |");
     225    for(int k = 1; k < 4; ++k)
     226    {
     227      printf(" \b%f ", V(j, k));
     228    }
     229    printf(" |\n");
     230  }
     231
     232  printf("New Jacobi\n");
     233  for(int j = 0; j < 3; ++j)
     234  {
     235    printf(" |");
     236    for(int k = 0; k < 3; ++k)
     237    {
     238      printf(" \b%f ", eigenvectors[j][k]);
     239    }
     240    printf(" |\n");
     241  }
    217242
    218243  axis[0] = new Vector(V(1, 1), V(2, 1), V(3, 1));
Note: See TracChangeset for help on using the changeset viewer.