Changeset 2909


Ignore:
Timestamp:
01/26/10 09:21:49 (15 years ago)
Author:
Mathieu Morlighem
Message:

Added very useful comments

File:
1 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk/src/c/Bamgx/objects/Geometry.cpp

    r2899 r2909  
    492492                Int4 i,j,k;
    493493                int jj;
    494                 Int4* hv=new Int4[nbv];
    495                 Int4* ev=new Int4[2*nbe];
     494                Int4* head_v=new Int4[nbv];
     495                Int4* next_p=new Int4[2*nbe];
    496496                float* eangle=new float[nbe];
    497497                double eps=1e-20;
     
    560560                }
    561561
    562                 //initialize hv as -1 for all vertices
    563                 for (i=0;i<nbv;i++) hv[i]=-1;
     562                /* Here we use a powerful chaining algorithm
     563                 *
     564                 * 1. What is a chaining algorithm?
     565                 *
     566                 * If F is a function that goes from i in [0 n] to j in [0 m]
     567                 * and we want to compute the reciprocal function F-1 of F
     568                 * (what are the antecedents of a given j in Im(F) )
     569                 * We use 2 lists:
     570                 *    head_F[j] that holds the head of lists
     571                 *    next_F[i] that holds the list of elements that have the same image
     572                 *
     573                 * Example:
     574                 *    i1, i2, ..., ip in [0,n] are all antecedents of a given j in [0 m]
     575                 *    head_F[j] = ip
     576                 *    next_F[ip]= ip-1
     577                 *    ....
     578                 *    next_F[i2]= i1
     579                 *    next_F[i1]= -1  //end of the list
     580                 *
     581                 * Algorithm:
     582                 *    for(j=0;j<m;j++)  head_F[j] = -1 //initialization
     583                 *    for(i=0;i<n;i++){
     584                 *       j=F[i];
     585                 *       next_F[i]= head_F[j];
     586                 *       head_F[j]=i;
     587                 *    }
     588                 *
     589                 *    Then, we can go through all the elements that have for image j:
     590                 *    for(i=head_F[j]; i!=-1; i=next_F[i])
     591                 *    initialization of i by i=head_F[j]
     592                 *    stop the loop when i=-1 (end of the chain)
     593                 *    iterate using i=next_F[i] (next element that have for image j)
     594                 *
     595                 * 2. How to use this algorithm here?
     596                 *
     597                 * Here F is a function that associates two vertices v0 and v1 for a given edge E
     598                 * We want to build the reciprocal function: what are the edges that contains
     599                 * a vertex v?
     600                 * To do so, we use the same chaining algorithm but there is a difficulty
     601                 * coming from the fact that F we have a couple of vertices and not one
     602                 * vertices.
     603                 * To overcome this difficulty, we use a global indices exactly like in
     604                 * C/C++ so that
     605                 * a member of a 2-column-table can be described by one index p=i*2+j
     606                 * i=(int)p/2 line number of p
     607                 * j=p%2       column number of p
     608                 *
     609                 * Algorithm:
     610                 *    for(i=0;i<nbv;i++)  head_v[i] = -1 //initialization
     611                 *    for(i=0;i<nbe;i++){
     612                 *       for(j=0;j<2;j++){
     613                 *          p=2*i+j;
     614                 *          v=edges(i,j);
     615                 *          next_p[p]= head_v[v];
     616                 *          head_v[v]=p;
     617                 *       }
     618                 *    }
     619                 */
     620
     621                //initialize head_v as -1
     622                for (i=0;i<nbv;i++) head_v[i]=-1;
    564623                k=0;
    565624                for (i=0;i<nbe;i++) {
     
    573632                        //compute angle in [-Pi Pi]
    574633                        eangle[i] = atan2(v10.y,v10.x);
    575                         //build hv and ev
     634                        //build chains head_v and next_p
    576635                        for (j=0;j<2;j++){
    577636                                Int4 v=Number(edges[i].v[j]);
    578                                 ev[k]=hv[v];
    579                                 hv[v]=k++;
    580                         }
    581                 }
    582                 // in our case, for 4 points and 4 edges (in parenthesis from now on):
    583                 // hv =  7 2 4 6
    584                 // ev =  -1 -1 1 -1 3 -1 5 0
    585 
    586                 //compute angle of edges
     637                                next_p[k]=head_v[v];
     638                                head_v[v]=k++; //post increment: head_v[v]=k; and then k=k+1;
     639                        }
     640                }
     641
     642                //sort head_v by order of increasing edges angle
    587643                for (i=0;i<nbv;i++) {
    588 
    589644                        int exch=1, ord=0;     
     645
     646                        //exchange vertices position in head_v and next_p till tey are sorted
    590647                        while (exch){
    591                                 Int4 *p=hv+i;                   // pointer to hv[vertex i]  (p=hv)
    592                                 Int4 *po=p;                     // copy of pointer p        (po=p)
    593                                 Int4  n=*p;                     // value hv[vertex i]       (n=7)
     648                                Int4 *p=head_v+i;               // pointer toward head_v[vertex i]
     649                                Int4 *po=p;                     // copy of pointer p
     650                                Int4  n=*p;                     // next value of edge holding i
    594651                                register float angleold=-1000 ; // angle = - infinity
    595652                                ord=0; exch=0;
    596                                 while (n >=0){// loop as long as ...
     653
     654                                // loop over the edges that contain the vertex i
     655                                while (n >=0){
    597656                                        ord++;
    598                                         register Int4  i1=n/2;       // i1 = floor (n/2)          (i1 = 7/2 = 3)
    599                                         register Int4  j1=n%2;       // j1 = 1 if n is odd        (j1 = 1)
    600                                         register Int4* pn=ev+n;      // pointer to ev[n]          (pn = &ev[7])
    601                                         //compute angle from eangle:
    602                                         // if n odd: angle = eangle - Pi [2*Pi]
    603                                         // else    : angle = eangle
    604                                         float angle = j1 ? OppositeAngle(eangle[i1]):  eangle[i1];
    605                                         n=*pn;                       //  n = ev[n]                (n = ev[7] = 0)
    606                                         if (angleold > angle){       // exch to have : po -> pn -> p
    607                                                 exch=1, *pn=*po, *po=*p, *p=n, po=pn;
     657                                        register Int4  i1=n/2;       // i1 = floor (n/2)
     658                                        register Int4  j1=n%2;       // j1 = 1 if n is odd
     659                                        register Int4* pn=next_p+n;  // pointer to next_p[n]
     660
     661                                        //  n = next_p[n] = position in edge of next vertex i
     662                                        n=*pn;                       
     663
     664                                        //compute angle between horizontal axis and v0->v1
     665                                        float angle = j1 ? OppositeAngle(eangle[i1]):  eangle[i1];
     666
     667                                        //exchange if the current edge angle is smaller than the previous one
     668                                        if (angleold > angle){
     669                                                exch=1;
     670                                                *pn=*po;  // next_p[n] = n + 1
     671                                                *po=*p;   //
     672                                                *p=n;     // next_p[n+1] = n
     673                                                po=pn;    // po now point toward pn (invert next and current)
    608674                                        }
     675
     676                                        //else, continue going to the next edge position
    609677                                        else{                        //  to have : po -> p -> pn
    610                                                 angleold=angle, po=p, p=pn;
     678                                                angleold=angle; // update maximum angle
     679                                                po=p;           // po now point toward p  (current position)
     680                                                p=pn;           // p  now point toward pn (next position)
    611681                                        }
    612682                                }
    613683                        }
    614                         //first iteration: i=0
    615                         //hv 0 2 4 6
    616                         //ev 7 -1 1 -1 3 -1 5 -1
    617 
    618                         // angular test on current vertex to guess whether it is a corner
     684                        printf("ord = %i\n",ord);
     685
     686                        // angular test on current vertex to guess whether it is a corner (ord = number of edges horlding i)
    619687                        if(ord == 2) {
    620                                 Int4  n1 = hv[i];
    621                                 Int4  n2 = ev[n1];
     688                                Int4  n1 = head_v[i];
     689                                Int4  n2 = next_p[n1];
    622690                                Int4  i1 = n1/2, i2 = n2/2; // edge number
    623691                                Int4  j1 = n1%2, j2 = n2%2; // vertex in the edge
    624                                 /*//first iteration i=0
    625                                 //n1=hv[i]=0
    626                                 //n2=ev[i]=7
    627                                 //i1 = 0  i2 = 3
    628                                 //j1 = 0  j2 = 1
    629                                 printf("i=%i\n",i);
    630                                 printf("n1=hv[i]=%i\n",n1);
    631                                 printf("n2=ev[i]=%i\n",n2);
    632                                 printf("i1 = %i  i2 = %i\n",i1,i2);
    633                                 printf("j1 = %i  j2 = %i\n",j1,j2);*/
    634692                                float angle1=  j1 ? OppositeAngle(eangle[i1]) : eangle[i1];
    635693                                float angle2= !j2 ? OppositeAngle(eangle[i2]) : eangle[i2];
     
    651709
    652710                        // close the liste around the vertex
    653                         Int4 no=-1, ne = hv[i];
    654                         while (ne >=0) ne = ev[no=ne];       
    655                         if(no>=0) ev[no] = hv[i];
     711                        Int4 no=-1, ne = head_v[i];
     712                        while (ne >=0) ne = next_p[no=ne];       
     713                        if(no>=0) next_p[no] = head_v[i];
    656714                        // now the list around the vertex is circular
    657715                }
     
    660718                for (i=0;i<nbe;i++){
    661719                        for (j=0;j<2;j++){
    662                                 Int4 n1 = ev[k++];
     720                                Int4 n1 = next_p[k++];
    663721                                Int4 i1 = n1/2 ,j1=n1%2;
    664722                                if( edges[i1].v[j1] != edges[i].v[j]) {
     
    765823
    766824                /*clean up*/
    767                 delete []ev;
    768                 delete []hv;
     825                delete []next_p;
     826                delete []head_v;
    769827                delete []eangle;
    770828
Note: See TracChangeset for help on using the changeset viewer.