00001
00002 #include <iostream>
00003 #include <fstream>
00004
00005
00006 #include <GL/gl.h>
00007
00008 #include "resollu.h"
00009
00010
00011 #include "snake.h"
00012
00013
00014
00015 Snake::Snake()
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;
00028 }
00029
00030
00031
00032
00033
00034
00035 Snake::Snake( std::vector< Vertex_handle > S , Polyhedron localRegion = Polyhedron())
00036 {
00037
00038 if (!localRegion.empty())
00039 {
00040 this->R=Region(localRegion) ;
00041 R.Compute_Parameterization() ;
00042 R_is_initialized=true;
00043
00044 Snake_VH = std::vector< Vertex_handle >(S);
00045
00046
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];
00064 this->Maj_A();
00065 }
00066 else
00067 {
00068 R_is_initialized=false;
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
00083
00084
00085
00086 Snake::Snake( std::vector< std::vector< Vertex_handle > > S, Polyhedron localRegion = Polyhedron() )
00087 {
00088
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
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) ;
00113 R.Compute_Parameterization() ;
00114 R_is_initialized=true;
00115
00116 Vertex_handle vh;
00117
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];
00139 this->Maj_A();
00140
00141 this->Energy_minimization(20);
00142
00143 }
00144 else
00145 {
00146 R_is_initialized=false;
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()
00163 {
00164 delete [] WeightsA;
00165 delete [] WeightsB;
00166 delete [] A;
00167 }
00168
00169
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
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
00199 glColor3f(0.8,0.2,0.2);
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
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();
00224
00225 glLineWidth(1.0);
00226 }
00227
00228
00229 void Snake::draw_snake3D() const
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
00243 glColor3f(0.8,0.2,0.2);
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
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();
00271
00272 glLineWidth(1.0);
00273 }
00274
00275
00276
00277 void Snake::Maj_A()
00278 {
00279
00280 if ( WeightsA!= NULL && WeightsB!= NULL )
00281 {
00282
00283 for(int i=0; i<dim; i++)
00284 {
00285 for(int j=0; j<dim; j++)
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
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++)
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
00366
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
00376
00377 double Snake_PosX[dim];
00378 double Snake_PosY[dim];
00379
00380
00381 double fx[dim];
00382 double fy[dim];
00383
00384 fx[0]=0;
00385 fy[0]=0;
00386
00387 Vertex_handle vh;
00388
00389 std::vector< Vertex_handle >::const_iterator it;
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++)
00399 {
00400
00401
00402
00403 this->Maj_A();
00404
00405
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
00411 for(int i=1; i<dim; i++)
00412 {
00413 vh=*it;
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
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
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
00436 for(int i=0; i<dim; i++) Snake_PosX[i] = B[i];
00437
00438 this->Maj_A();
00439
00440
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
00451 for(int i=0; i<dim; i++) Snake_PosY[i] = B[i];
00452
00453
00454
00455
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
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
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