/home/ann2.ext/paccaulf/projsem2/ContourActif/snake.cpp

Aller à la documentation de ce fichier.
00001 // STL stuff 
00002 #include <iostream> 
00003 #include <fstream>
00004 
00005 // OpenGL stuff
00006 #include <GL/gl.h>
00007 
00008 #include "resollu.h"
00009 
00010 
00011 #include "snake.h"
00012 
00013 
00014 
00015 Snake::Snake() //Default constructor (ca ne sert a rien de reserver de la memoire pour rien...)
00016 {
00017         Pas_Gamma=1;
00018         
00019         Snake_VH = std::vector< Vertex_handle >();
00020         dim=0;
00021         
00022         WeightsA = NULL;
00023         WeightsB = NULL;
00024         
00025         A = NULL; 
00026         
00027     R_is_initialized=false; // la region associee au snake n'est pas valide pour le moment
00028 }
00029         
00030     
00031 /*
00032   The user input is utilized for initially approximating the features 
00033   detection process
00034 */
00035 Snake::Snake( std::vector< Vertex_handle > S , Polyhedron localRegion = Polyhedron())
00036 {
00037         
00038         if (!localRegion.empty())
00039         {
00040                 this->R=Region(localRegion) ; // contruction de la region
00041                 R.Compute_Parameterization() ; // parametrisation
00042                 R_is_initialized=true;  
00043                 
00044                 Snake_VH = std::vector< Vertex_handle >(S); // utilisation du constructeur par copie
00045                 
00046                 // Passage aux points 2D
00047                 for(std::vector< Vertex_handle >::iterator it=Snake_VH.begin(); it != Snake_VH.end(); it++)
00048                              R.vh2Dfrom3D(*it); 
00049         
00050                 dim=Snake_VH.size();
00051                 
00052                 WeightsA = new double[dim];
00053                 WeightsB = new double[dim];
00054                 
00055                 
00056                 for(int i=0; i<dim; i++)
00057                 {
00058                         WeightsA[i]=1;
00059                         WeightsB[i]=1;                     
00060                 }
00061                 
00062                 
00063                 A = new double [dim][200]; // allocation memoire
00064                 this->Maj_A();
00065         }
00066         else
00067         {
00068                 R_is_initialized=false; // la region associee au snake n'est pas valide pour le moment
00069                 
00070                 Snake_VH = std::vector< Vertex_handle >();
00071                 dim=0;
00072                 
00073                 WeightsA = NULL;
00074                 WeightsB = NULL;
00075                 
00076                 A = NULL; 
00077         }
00078         
00079 }
00080 
00081 /*
00082   The user input is utilized for initially approximating the features 
00083   detection process
00084 */
00085 
00086 Snake::Snake( std::vector< std::vector< Vertex_handle > > S, Polyhedron localRegion = Polyhedron() )
00087 {
00088         //defensif
00089         
00090         Snake_VH.clear() ;
00091         
00092         Snake_VH = std::vector< Vertex_handle >();
00093         
00094         std::vector< Vertex_handle > Sninter = std::vector< Vertex_handle >();
00095         
00096         // besoin de sortir unSommet des deux for imbriques pour pouvoir faire le push_back a la suite
00097         std::vector< Vertex_handle >::iterator unSommet ;
00098         for (std::vector< std::vector< Vertex_handle > >::iterator unSegment = S.begin() ; 
00099                  unSegment != S.end() ; 
00100                  unSegment++) 
00101           {
00102                 unSommet = unSegment->begin() ;
00103                 for ( ; unSommet != unSegment->end() ; unSommet++) 
00104                   {
00105                         if (*unSommet != *(unSegment->end())) Sninter.push_back(*unSommet) ;
00106                   }
00107           }
00108         
00109         
00110         if (!localRegion.empty())
00111         {
00112                 this->R=Region(localRegion) ; // contruction de la region
00113                 R.Compute_Parameterization() ; // parametrisation
00114                 R_is_initialized=true;  
00115                 
00116                 Vertex_handle vh;
00117                 // Passage aux points 2D
00118                 for(std::vector< Vertex_handle >::iterator it=Sninter.begin(); it != Sninter.end(); it++)
00119                 {
00120                         vh=*it;
00121                         R.vh2Dfrom3D(vh); 
00122                         Snake_VH.push_back(vh);
00123                 }
00124                 
00125                 dim=Snake_VH.size();
00126                 
00127                 WeightsA = new double[dim];
00128                 WeightsB = new double[dim];
00129                 
00130                 
00131                 for(int i=0; i<dim; i++)
00132                 {
00133                         WeightsA[i]=1;
00134                         WeightsB[i]=1;                     
00135                 }
00136                 
00137                 
00138                 A = new double [dim][200]; // allocation memoire
00139                 this->Maj_A();
00140                 
00141                 this->Energy_minimization(20); 
00142 
00143         }
00144         else
00145         {
00146                 R_is_initialized=false; // la region associee au snake n'est pas valide pour le moment
00147                 
00148                 Snake_VH.clear() ;
00149                 Snake_VH = std::vector< Vertex_handle >();
00150                 
00151                 dim=0;
00152                 
00153                 WeightsA = NULL;
00154                 WeightsB = NULL;
00155                 
00156                 A = NULL; 
00157         }
00158         
00159         
00160 }
00161 
00162 Snake::~Snake() //Destructor
00163 {
00164   delete [] WeightsA;  
00165   delete [] WeightsB; 
00166   delete [] A;  
00167 }
00168         
00169 // Methods
00170 void Snake::Affiche_snake() const
00171 {   
00172         if(Snake_VH.size()==0) std::cout << "Snake vide" << std::endl;
00173         else {
00174                 int count=1;
00175                 for(std::vector< Vertex_handle >::const_iterator it=Snake_VH.begin(); it != Snake_VH.end(); it++)
00176                 {
00177                         std::cout << "Point numero " << count++ << std::endl;
00178                         std::cout << "   [" << (*it)->point()[0] << "][" << (*it)->point()[1] << "][" << (*it)->point()[2] << "]" << std::endl;
00179                 }
00180         }
00181         
00182 }
00183 
00184 
00185 void Snake::draw_snake2D() const // Pour dessiner le snake 2D (OpenGl)
00186 {
00187         if(Snake_VH.size()==0)          
00188         {               
00189                 std::cout << "WARNING in draw_snake: the snake is empty." << std::endl; 
00190         }       
00191         if(Snake_VH.size()==1)          
00192         {               
00193                 std::cout << "WARNING in draw_snake: the snake contains only one point." << std::endl;  
00194         }       
00195         
00196         glClear(1);
00197         
00198         // draw lines
00199         glColor3f(0.8,0.2,0.2); // red
00200         glLineWidth(10.0);
00201         
00202         std::vector< Vertex_handle >::const_iterator it; 
00203         it=Snake_VH.begin();
00204         
00205         Point p1, p2;
00206         
00207         glDisable(GL_LIGHTING) ;
00208         
00209         glBegin(GL_LINES);
00210         
00211         p2==(*it)->point();
00212         while( (it!=Snake_VH.end()) && (++it!=Snake_VH.end()) ){
00213                 p1=p2;
00214                 p2=(*it)->point();
00215                 // opengl
00216                 glVertex3f(p1[0],p1[1],p1[2]);
00217                 glVertex3f(p2[0],p2[1],p2[2]);
00218                 
00219         }
00220         
00221         glEnd(); 
00222         glEnable(GL_LIGHTING) ;
00223         glFlush(); // pour la mise a jour
00224                 
00225         glLineWidth(1.0); // on redonne une largeur normale a la ligne
00226 }
00227 
00228 
00229 void Snake::draw_snake3D() const // Pour dessiner le snake 3D (OpenGl)
00230 {
00231         if(Snake_VH.size()==0)          
00232         {               
00233                 std::cout << "WARNING in draw_snake: the snake is empty." << std::endl; 
00234         }       
00235         if(Snake_VH.size()==1)          
00236         {               
00237                 std::cout << "WARNING in draw_snake: the snake contains only one point." << std::endl;  
00238         }       
00239         
00240         
00241         
00242         // draw lines
00243         glColor3f(0.8,0.2,0.2); // red
00244         glLineWidth(20.0);
00245         
00246         std::vector< Vertex_handle >::const_iterator it; 
00247         it=Snake_VH.begin();
00248         
00249         Point p1, p2;
00250         
00251         glDisable(GL_LIGHTING) ;
00252         
00253         glBegin(GL_LINES);
00254         
00255         p2==(*it)->point();
00256         R.Point3D_from_2D(p2);
00257         while( (it!=Snake_VH.end()) && (++it!=Snake_VH.end()) ){
00258                 p1=p2;
00259                 p2=(*it)->point();
00260                 R.Point3D_from_2D(p2);
00261                 // opengl
00262                 glVertex3f(p1[0],p1[1],p1[2]);
00263                 glVertex3f(p2[0],p2[1],p2[2]);
00264                 
00265         }
00266         
00267         glEnd(); 
00268         glEnable(GL_LIGHTING) ;
00269         
00270         glFlush(); // pour la mise a jour
00271         
00272         glLineWidth(1.0); // on redonne une largeur normale a la ligne
00273 }
00274                 
00275 
00276 // operationnel (teste) 
00277 void Snake::Maj_A() // Maj de A en fonction des poids (attention a ne pas le faire pour rien)
00278 {
00279         
00280         if ( WeightsA!= NULL && WeightsB!= NULL )
00281           {
00282                 
00283         for(int i=0; i<dim; i++) //parcours des lignes de A
00284                   {
00285                 for(int j=0; j<dim; j++) //parcours des colonnes de A
00286                           {
00287                                 if (i == 0) 
00288                                         switch (j)
00289                                           {
00290                         case 0: 
00291                                                         A[i][j]= WeightsA[i]+WeightsA[i+1]+4*WeightsB[i]+WeightsB[i+1];
00292                                                         break;
00293                         case 1: 
00294                                                         A[i][j]=-WeightsA[i+1]-2*WeightsB[i]-2*WeightsB[i+1];
00295                                                         break;
00296                         case 2: 
00297                                                         A[i][j]=WeightsB[i+1];
00298                                                         break;
00299                         default:
00300                                                         A[i][j]=0 ;
00301                                                         break;
00302                                           }
00303                                                 else if (i == dim-1)        
00304                                                         if (j == i-2)
00305                                 A[i][j]=WeightsB[i-1];
00306                                                         else if (j==i-1)
00307                                 A[i][j]=-WeightsA[i]-2*WeightsB[i-1]-2*WeightsB[i];
00308                                                         else if (j==i)
00309                                 A[i][j]=WeightsA[i]+WeightsB[i-1]+4*WeightsB[i];
00310                                                         else A[i][j]=0;           
00311                                         else
00312                         if (j == i-2) 
00313                                                         A[i][j]=WeightsB[i-1];
00314                                         else if (j == i-1)
00315                                                 A[i][j]=-WeightsA[i]-2*WeightsB[i-1]-2*WeightsB[i];
00316                                         else if (j == i)
00317                                                 A[i][j]=WeightsA[i]+WeightsA[i+1]+WeightsB[i-1]+4*WeightsB[i]+WeightsB[i+1];
00318                                         else if (j == i+1)
00319                                                 A[i][j]=-WeightsA[i+1]-2*WeightsB[i]-2*WeightsB[i+1];
00320                                         else if (j == i+2)
00321                                                 A[i][j]=WeightsB[i+1];
00322                                         else A[i][j]=0;
00323                                 
00324                           }
00325             
00326                   }   
00327                 
00328           }else {
00329                   std::cout << "A cannot be modified without initializing WeightsA and WeightsB. " << std::endl; 
00330           }
00331         
00332 }
00333 
00334 
00335 // Modifieur et accesseur de la matrice A (pour des tests au cas ou...)
00336 void Snake::Set_A(int i,int j, double f)
00337 {
00338   A[i][j]=f;
00339 }
00340         
00341 void Snake::Affiche_A()
00342 {
00343         if (A==NULL) std::cout << "La matrice A est vide." << std::endl;
00344         else {
00345                 
00346                 for (int i=0; i<dim; i++) // affichage de la ligne i
00347                   {
00348                         for (int j=0; j<dim; j++) std::cout << "["<< A[i][j] << "]";
00349                         
00350                         std::cout << std::endl;
00351                   }
00352                 
00353         }
00354         
00355         
00356 }
00357 
00358 double Snake::Get_A(int i,int j)
00359 {
00360   return A[i][j];
00361 }
00362                 
00363                                                         
00364                                                       
00365 // Pour la mise a jour des points 2D du snake dans le processus de minimisation d'NRJ
00366 // n'est adaptee que pour la parametrisation sur un carre de cote 6 unites
00367 void Snake::Energy_minimization(int n_iterations)       
00368 {   
00369         
00370         if (R_is_initialized) {
00371                 
00372         double B[dim];  
00373         int count=0;
00374                 
00375                 // the current positions of the snake
00376                 // of course we must have the same number n of 2 and 3D positions
00377                 double Snake_PosX[dim];
00378                 double Snake_PosY[dim];
00379                 
00380                 // pour le calcul de l'nrj feature des points du snake
00381                 double fx[dim];  
00382                 double fy[dim];
00383                 // comment determiner l'nrj du premier point du snake?????????
00384                 fx[0]=0;
00385                 fy[0]=0;        
00386                 
00387                 Vertex_handle vh;
00388                 
00389                 std::vector< Vertex_handle >::const_iterator it; // notre iterator de vecteur
00390                 for(it=Snake_VH.begin(); it!=Snake_VH.end(); it++)        
00391                   {
00392                         Snake_PosX[count++]=(*it)->point()[0];
00393                         Snake_PosY[count++]=(*it)->point()[1];
00394                         
00395                   }                                       
00396                 
00397                 
00398         for(int n=0; n<n_iterations; n++) // on a un nb d'iteration fixe pour l'evolution de notre snake dans le polyhedre 2D
00399                   {             
00400                         
00401                         //this->Affiche_snake(); // debug
00402                         
00403                         this->Maj_A(); // Calcul de la matrice A ici car A est modifiee par ResoudreSysteme (ou premiere it)
00404                         
00405                         // modif de A 
00406                         for (int i=0; i<dim; i++) this->Set_A(i, i, this->Get_A(i,i) + this->Get_Pas_Gamma() ); 
00407                         
00408                         
00409                         it=Snake_VH.begin(); 
00410                         // on calcule les nouvelles derivees partielles
00411                         for(int i=1; i<dim; i++) 
00412                           {
00413                                 vh=*it; // vertex handle precedent
00414                                 it++;                           
00415                                 
00416                                 if ( Snake_PosX[i]-Snake_PosX[i-1] != 0 ) 
00417                                         fx[i]=( R.Nrj_sommet(*it) - R.Nrj_sommet(vh) )/(Snake_PosX[i]-Snake_PosX[i-1]); 
00418                                 
00419                                 if ( Snake_PosY[i]-Snake_PosY[i-1] != 0 ) 
00420                                         fy[i]=( R.Nrj_sommet(*it) - R.Nrj_sommet(vh) )/(Snake_PosY[i]-Snake_PosY[i-1]); 
00421                                 }
00422                         
00423                         // on prend en compte les dp
00424                         for(int i=0; i<dim; i++) Snake_PosX[i] += -fx[i];
00425                         
00426                         for(int i=0; i<dim; i++) Snake_PosY[i] += -fy[i];
00427                         
00428                         // on resoud notre systeme
00429                         if ( !ResoudreSysteme(A, Snake_PosX, B, dim) )
00430                           {
00431                                 std::cerr << "ERROR IN ResoudreSysteme occured with Snake_PosX." << std::endl;
00432                                 exit(-1);
00433                           }
00434                         
00435                         // maintenant il faut remettre a jour Snake_PosX                
00436                         for(int i=0; i<dim; i++) Snake_PosX[i] = B[i]; 
00437                         
00438                         this->Maj_A(); // Calcul de la matrice A ici car A est modifiee par ResoudreSysteme
00439                         
00440                         // modif de A 
00441                         for (int i=0; i<dim; i++) this->Set_A(i, i, this->Get_A(i,i) + this->Get_Pas_Gamma() );         
00442                         
00443                         
00444                         if ( !ResoudreSysteme(A, Snake_PosY, B, dim) )
00445                           {
00446                                 std::cerr << "ERROR IN ResoudreSysteme occured with Snake_PosY." << std::endl;
00447                                 exit(-1);        
00448                           }
00449                         
00450                         // maintenant il faut remettre a jour Snake_PosY                
00451                         for(int i=0; i<dim; i++) Snake_PosY[i] = B[i];
00452                         
00453                         
00454                         // on met a jour notre snake de telle sorte 
00455                         // que les points du snake reste dans le carre
00456                         count=0;
00457                         
00458                         for(it=Snake_VH.begin(); it!=Snake_VH.end(); it++)        
00459                           {     
00460                                 if(0 <= Snake_PosX[count] && Snake_PosX[count]<=6 && 0 <= Snake_PosY[count] && Snake_PosY[count]<=6 )
00461                                 {Point p(Snake_PosX[count],Snake_PosY[count++],0);
00462                                 
00463                                 (*it)->point() = p;
00464                                 
00465                                 }
00466                                 
00467                                 count++;
00468                           }
00469                         
00470                   }
00471                 
00472                 
00473         } else std::cerr << "The local region associated with the snake must be initialized to compute the energy minimization process." << std::endl; 
00474         
00475         
00476         
00477 }
00478         
00479 // Modifieur et accesseur du pas gamma
00480 void Snake::Set_Pas_Gamma(double f)     
00481 {
00482   Pas_Gamma=f;
00483 }
00484         
00485 double Snake::Get_Pas_Gamma()   
00486 {
00487   return Pas_Gamma;
00488 }
00489        
00490                 
00491 int Snake::Get_dim()
00492 {
00493   return dim;
00494 }        
00495                    
00496 // Modifieur et accesseur des poids
00497 void Snake::Set_Snake_WeightsA( double* Vec, int taille )       
00498 {
00499   if (dim==taille) 
00500     {
00501       for(int i=0; i<dim; i++)
00502         {
00503           WeightsA[i]= Vec[i];      
00504         }            
00505     }
00506   else std::cerr << "ERROR IN Set_Snake_WeightsA( double* Vec, int taille ): taille must have the same value than dim. " << std::endl;
00507                           
00508 }
00509         
00510 void Snake::Set_Snake_WeightsB( double* Vec, int taille )
00511 {
00512   if (dim==taille) 
00513     {
00514       for(int i=0; i<dim; i++)
00515         {
00516           WeightsB[i]= Vec[i];      
00517         }            
00518     }
00519   else std::cerr << "ERROR IN Set_Snake_WeightsB( double* Vec, int taille ): taille must have the same value than dim." << std::endl;
00520                 
00521 }
00522         
00523 double* Snake::Get_Snake_WeightsA()     
00524 {
00525   return WeightsA;
00526 }
00527         
00528 double* Snake::Get_Snake_WeightsB()
00529 {
00530   return WeightsB;
00531 }
00532             
00533             

Généré le Thu Jun 15 18:48:52 2006 pour Projet Image 2006 - Vincent Vidal, Florent Paccault - par  doxygen 1.4.7