Changeset 2909
- Timestamp:
- 01/26/10 09:21:49 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/c/Bamgx/objects/Geometry.cpp
r2899 r2909 492 492 Int4 i,j,k; 493 493 int jj; 494 Int4* h v=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]; 496 496 float* eangle=new float[nbe]; 497 497 double eps=1e-20; … … 560 560 } 561 561 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; 564 623 k=0; 565 624 for (i=0;i<nbe;i++) { … … 573 632 //compute angle in [-Pi Pi] 574 633 eangle[i] = atan2(v10.y,v10.x); 575 //build hv and ev634 //build chains head_v and next_p 576 635 for (j=0;j<2;j++){ 577 636 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 587 643 for (i=0;i<nbv;i++) { 588 589 644 int exch=1, ord=0; 645 646 //exchange vertices position in head_v and next_p till tey are sorted 590 647 while (exch){ 591 Int4 *p=h v+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 594 651 register float angleold=-1000 ; // angle = - infinity 595 652 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){ 597 656 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) 608 674 } 675 676 //else, continue going to the next edge position 609 677 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) 611 681 } 612 682 } 613 683 } 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) 619 687 if(ord == 2) { 620 Int4 n1 = h v[i];621 Int4 n2 = ev[n1];688 Int4 n1 = head_v[i]; 689 Int4 n2 = next_p[n1]; 622 690 Int4 i1 = n1/2, i2 = n2/2; // edge number 623 691 Int4 j1 = n1%2, j2 = n2%2; // vertex in the edge 624 /*//first iteration i=0625 //n1=hv[i]=0626 //n2=ev[i]=7627 //i1 = 0 i2 = 3628 //j1 = 0 j2 = 1629 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);*/634 692 float angle1= j1 ? OppositeAngle(eangle[i1]) : eangle[i1]; 635 693 float angle2= !j2 ? OppositeAngle(eangle[i2]) : eangle[i2]; … … 651 709 652 710 // close the liste around the vertex 653 Int4 no=-1, ne = h v[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]; 656 714 // now the list around the vertex is circular 657 715 } … … 660 718 for (i=0;i<nbe;i++){ 661 719 for (j=0;j<2;j++){ 662 Int4 n1 = ev[k++];720 Int4 n1 = next_p[k++]; 663 721 Int4 i1 = n1/2 ,j1=n1%2; 664 722 if( edges[i1].v[j1] != edges[i].v[j]) { … … 765 823 766 824 /*clean up*/ 767 delete [] ev;768 delete []h v;825 delete []next_p; 826 delete []head_v; 769 827 delete []eangle; 770 828
Note:
See TracChangeset
for help on using the changeset viewer.