Curve_3D.cpp

Go to the documentation of this file.
00001 
00002 #include <Curve_3D.h>
00003 
00004 Curve_3D::Curve_3D():data()
00005 {
00006   data.resize(0);
00007 }
00008 
00009 Curve_3D::~Curve_3D()
00010 {
00011   destroy();
00012 }
00013 
00014 Curve_3D::Curve_3D(const Curve_3D& _curve):data()
00015 {data = _curve.data;}
00016 
00017 int Curve_3D::destroy()
00018 {data.resize(0);return 0;}
00019 
00020 int Curve_3D::size() const
00021 {return data.size();}
00022 
00023 int Curve_3D::add(const V_3D& point)
00024 {data.push_back(point);return 0;}
00025 int Curve_3D::add_point(const V_3D& point)
00026 {data.push_back(point);return 0;}
00027 
00028 V_3D& Curve_3D::get(int k_index)
00029 {
00030   if(k_index<0 || k_index>=size())
00031     {printf("Error k_index [%d] not in bounds in get in Curve_3D (size=%d)\n",k_index,size());exit(-1);}
00032   return data[k_index];
00033 }
00034 V_3D Curve_3D::get(int k_index) const
00035 {
00036   if(k_index<0 || k_index>=size())
00037     {printf("Error k_index [%d] not in bounds in get in Curve_3D (size=%d)\n",k_index,size());exit(-1);}
00038   return data[k_index];
00039 }
00040 V_3D& Curve_3D::operator[](int k_index)
00041 {
00042   if(k_index<0 || k_index>=size())
00043     {printf("Error k_index [%d] not in bounds in operator[] in Curve_3D (size=%d)\n",k_index,size());exit(-1);}
00044   return data[k_index];
00045 }
00046 V_3D  Curve_3D::operator[](int k_index) const
00047 {
00048   if(k_index<0 || k_index>=size())
00049     {printf("Error k_index [%d] not in bounds in operator[] in Curve_3D (size=%d)\n",k_index,size());exit(-1);}
00050   return data[k_index];
00051 }
00052   
00053 Curve_3D& Curve_3D::operator=(const Curve_3D& _curve)
00054 {
00055   int N_points=_curve.size();
00056   data.resize(N_points);
00057   for(int k=0;k<N_points;k++)
00058     data[k] = _curve.data[k];
00059   return *this;
00060 }
00061 
00062 
00063 int Curve_3D::resample_closed(int N)
00064 {
00065   int k=0;
00066 
00067   std::vector <V_3D> data2;
00068   double rho=0.5;
00069   double n20=1.0,n31=1.0;
00070   
00071 //   int size_1=size();
00072 //   double u=0.0;
00073 //   int u0=0,u1=0;
00074 //   double s=0.0;
00075 //   for(k=0;k<N;k++)
00076 //     {
00077 //       u=double(k/double(N-1)*(size()));
00078 //       u0=int(u);
00079 //       s=u-u0;
00080 //       u1=u0+1;
00081 //       //for close curve
00082 //       if(u1==size())
00083 //      u1=0;
00084 //       if(u0==size())
00085 //      {u1=1;u0=0;}
00086 //       data2.push_back(
00087 //                   (1.0-s)*data[u0] + s*data[u1]);
00088 //     }
00089 //   data2.push_back(data[size_1-1]);
00090 //   data = data2;
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100   //int size_1=size();
00101   double u=0.0;
00102   int u0=0,u1=0,u2=0,u3=0;
00103   double s=0.0;
00104 
00105   for(k=0;k<N;k++)
00106     {
00107       u=double(k/double(N)*(size()));
00108       u1=int(u);
00109       u2=u1+1;
00110       u3=u1+2;
00111       u0=u1-1;
00112       s=(u-u1)/(u2-u1);
00113       u1=u0+1;
00114 
00115       if(u0==-2)
00116         {u0=size()-2;u1=size()-1;}
00117       if(u0==-1)
00118         {u0=size()-1;}
00119       if(u3==size())
00120         {u3=0;}
00121       if(u3==size()+1)
00122         {u3=1;u2=0;}
00123       if(u3==size()+2)
00124         {u3=2;u2=1;u1=0;}
00125 
00126       //      data2.push_back((1-s)*data[u1]+s*data[u2]);
00127 //       data2.push_back(
00128 //                    data[u1]
00129 //                    +
00130 //                    s*(data[u2]-data[u0])
00131 //                    +
00132 //                    s*s*(2*(data[u0]-data[u1])+data[u2]-data[u3])
00133 //                    +
00134 //                    s*s*s*(data[u3]-data[u2]-data[u0]+data[u1])
00135 //                    );
00136       
00137 
00138 
00139       //n20=(data[u2]-data[u0]).norm();
00140       //n31=(data[u3]-data[u1]).norm();
00141       data2.push_back(
00142                       data[u1]
00143                       +
00144                       s*(data[u2]-data[u0])/n20*rho
00145                       +
00146                       s*s*(3*(data[u2]-data[u1])-2*(data[u2]-data[u0])/n20*rho-(data[u3]-data[u1])/n31*rho)
00147                       +
00148                       s*s*s*((data[u3]-data[u1])/n31*rho+(data[u2]-data[u0])/n20*rho+2*(data[u1]-data[u2]))
00149                       );
00150 
00151 
00152     }
00153   //data2.push_back(data[size_1-1]);
00154   data = data2;
00155 
00156 
00157   //Le code C permettant d'interpoler cubiquement quatre valeurs dans la plage mu [0...1] est le suivant :
00158 //     double interpolationCubique(double y0,double y1,double y2,double y3,double mu)
00159 //   {
00160 //      double a0,a1,a2,a3,mu2;
00161   
00162 //      mu2 = mu*mu;
00163 //      a0 = y3 - y2 - y0 + y1;
00164 //      a1 = y0 - y1 - a0;
00165 //      a2 = y2 - y0;
00166 //      a3 = y1;
00167   
00168 //      return (a0*mu*mu2+a1*mu2+a2*mu+a3);
00169 //   }
00170 
00171 
00172 
00173   return 0;
00174 }
00175 
00176 
00177 
00178 
00179 
00180 std::vector <V_3D> Curve_3D::get_diff_closed_curve() const
00181 {
00182   std::vector <V_3D> diff;
00183 
00184   int k_vertex=0;
00185   int N_vertex=size();
00186   double L;
00187   for(k_vertex=0;k_vertex<N_vertex;k_vertex++)
00188     {
00189       if(k_vertex>=1 && k_vertex<N_vertex-1)
00190         {
00191           L = (get(k_vertex+1)-get(k_vertex)).norm()+(get(k_vertex)-get(k_vertex-1)).norm();
00192           diff.push_back(
00193                          1.0/L*
00194                          (get(k_vertex+1)-get(k_vertex-1)));
00195         }
00196       else if(k_vertex==0)
00197         {
00198           L = (get(1)-get(0)).norm()+(get(0)-get(N_vertex-1)).norm();
00199           diff.push_back(
00200                          1.0/L*
00201                          (get(1)-get(N_vertex-1)));
00202         }
00203       else if(k_vertex==N_vertex-1)
00204         {
00205           L = (get(0)-get(N_vertex-1)).norm()+(get(N_vertex-1)-get(N_vertex-2)).norm();
00206           diff.push_back(
00207                          1.0/L*
00208                          (get(0)-get(N_vertex-2)));
00209         }
00210     }
00211   return diff;
00212 }
00213 
00214 
00215 std::vector <V_3D> Curve_3D::get_diff2_closed_curve() const
00216 {
00217   std::vector <V_3D> diff2;
00218 
00219   int k_vertex=0;
00220   int N_vertex=size();
00221   double L;
00222   for(k_vertex=0;k_vertex<N_vertex;k_vertex++)
00223     {
00224       if(k_vertex>=1 && k_vertex<N_vertex-1)
00225         {
00226           L = (get(k_vertex+1)-get(k_vertex)).norm()+(get(k_vertex)-get(k_vertex-1)).norm();
00227           diff2.push_back(
00228                           1.0/(L*L)*
00229                           (get(k_vertex+1)-2*get(k_vertex)+get(k_vertex-1)));
00230         }
00231       else if(k_vertex==0)
00232         {
00233           L = (get(1)-get(0)).norm()+(get(0)-get(N_vertex-1)).norm();
00234           diff2.push_back(
00235                          1.0/(L*L)*
00236                          (get(1)-2*get(0)+get(N_vertex-1)));
00237         }
00238       else if(k_vertex==N_vertex-1)
00239         {
00240           L = (get(0)-get(N_vertex-1)).norm()+(get(N_vertex-1)-get(N_vertex-2)).norm();
00241           diff2.push_back(
00242                          1.0/(L*L)*
00243                          (get(0)-2*get(N_vertex-1)+get(N_vertex-2)));
00244         }
00245     }
00246   return diff2;
00247 }
00248 
00249 
00250 
00251 std::vector <double> Curve_3D::get_curvature_closed_curve() const
00252 {
00253 
00254    std::vector <V_3D> diff,diff2;
00255    std::vector <double> curvature;
00256 
00257   diff  = get_diff_closed_curve();
00258   diff2 = get_diff2_closed_curve();
00259 
00260 
00261    int k_vertex=0;
00262    int N_vertex=size();
00263 
00264   curvature.resize(N_vertex);
00265   for(k_vertex=0;k_vertex<N_vertex;k_vertex++)
00266     {
00267       //normalize vector
00268       curvature[k_vertex] = 
00269         (diff[k_vertex].vector_prod(diff2[k_vertex])).norm()
00270         /
00271         (diff[k_vertex].norm()*diff[k_vertex].norm()*diff[k_vertex].norm())
00272         ;
00273      }
00274 
00275   return curvature;
00276 
00277 
00278 
00279   
00280 
00281 }
00282 
00283 
00284 
00285 double Curve_3D::length() const
00286 {
00287   double L=0.0;
00288   int N_data=data.size();
00289   int k_data=0;
00290   for(k_data=0;k_data<N_data-1;k_data++)
00291     L += (get(k_data+1)-get(k_data)).norm();
00292   return L;
00293 }
00294 
00295 
00296 
00297 Curve_3D Curve_3D::part(int k_0,int k_1) const
00298 {
00299   Curve_3D curve;
00300   
00301   if(k_0<0 || k_0>=size() || k_1<=0 || k_1>=size() || k_0>k_1)
00302     {printf("Error in part(%d,%d) in Curve_3D, parameters are not correct\n",k_0,k_1);exit(-1);}
00303     
00304   int k=0;
00305   for(k=k_0;k<=k_1;k++)
00306     curve.add_point(get(k));
00307   
00308   return curve;
00309 }
00310 
00311 Curve_3D Curve_3D::part_closed(int k_0,int k_1) const
00312 {
00313   Curve_3D curve;
00314 
00315   if(k_0<0 || k_0>=size() || k_1<0 || k_1>=size())
00316     {printf("Error in part_closed(%d,%d) in Curve_3D, parameters are not correct\n",k_0,k_1);exit(-1);}
00317     
00318   int dist_1=0,dist_2=0;
00319   dist_1=k_1-k_0;
00320   dist_2=size()-abs(dist_1);
00321 
00322 
00323 
00324   int k=0;
00325   if(fabs(dist_1)<=dist_2)
00326     {
00327       if(k_0<=k_1)
00328         for(k=k_0;k<=k_1;k++)
00329           curve.add_point(get(k));
00330       else
00331         for(k=k_0;k!=k_1;k=(k-1<0?size()-1:k-1))
00332           curve.add_point(get(k));
00333     }
00334   else
00335     {
00336       if(k_0<=k_1)
00337         for(k=k_0;k!=k_1;k=(k-1<0?size()-1:k-1))
00338           curve.add_point(get(k));
00339       else
00340         for(k=k_0;k!=k_1;k=(k+1)%size())
00341           curve.add_point(get(k));      
00342     }
00343 
00344   
00345   return curve;
00346 }
00347 
00348 int Curve_3D::add(const Curve_3D& _curve)
00349 {
00350   int k=0;
00351   for(k=0;k<_curve.size();k++)
00352     add_point(_curve.get(k));
00353   return 0;
00354 }
00355 
00356 int Curve_3D::add_first(const V_3D& point)
00357 {
00358   int ok=0;
00359   Curve_3D temp=*this;
00360   ok += destroy();
00361   ok += add(point);
00362   ok += add(temp);
00363   return ok;
00364 }
00365 
00366 
00367 Curve_3D Curve_3D::resample_part_closed(int k_0,int k_1,int N)
00368 {
00369 
00370   Curve_3D curve_part;
00371   curve_part = part_closed(k_0,k_1);
00372   curve_part.resample(N);
00373 
00374 
00375   
00376   int dist_1=0,dist_2=0;
00377   dist_1=k_1-k_0;
00378   dist_2=size()-abs(k_1-k_0);//pass through 0
00379   int k=0;
00380   if(dist_1<=dist_2)
00381     {
00382       if(k_0<=k_1)
00383         for(k=k_1;k!=k_0;k=(k+1)%size())
00384           curve_part.add_point(get(k));
00385       else
00386         for(k=k_1;k!=k_0;k=(k-1<0?size()-1:k-1))
00387           curve_part.add_point(get(k));
00388     }
00389   else
00390     {
00391       if(k_0<=k_1)
00392         for(k=k_1;k!=k_0;k=(k-1<0?size()-1:k-1))
00393           curve_part.add_point(get(k));
00394       else
00395         for(k=k_1;k!=k_0;k=(k+1)%size())
00396           curve_part.add_point(get(k)); 
00397     }
00398 
00399   return curve_part;
00400 }
00401 
00402 
00403 
00404 
00405 int Curve_3D::resample(int N)
00406 {
00407   int k=0;
00408 
00409   std::vector <V_3D> data2;
00410   double rho=0.5;
00411   double n20=1.0,n31=1.0;
00412 
00413 
00414   V_3D A,B,C,D;
00415   
00416 
00417   //int size_1=size();
00418   double u=0.0;
00419   int u0=0,u1=0,u2=0,u3=0;
00420   double s=0.0;
00421 
00422   for(k=0;k<N;k++)
00423     {
00424       u=double(k/double(N-1)*(size()-1));
00425       u1=int(u);
00426       u2=u1+1;
00427       u3=u1+2;
00428       u0=u1-1;
00429       s=(u-u1)/(u2-u1);
00430       u1=u0+1;
00431 
00432       if(u0==-1)
00433         {A= data[u1];}
00434       if(u3==size())
00435         {D= data[u2];}
00436       if(u3==size()+1)
00437         {C= data[u1]; D=data[u1];}
00438 
00439       if(u0>=0)
00440         A=data[u0];
00441       B=data[u1];
00442       if(u2<size())
00443         C=data[u2];
00444       if(u3<size())
00445         D=data[u3];
00446 
00447       //n31=(data[u3]-data[u1]).norm();
00448       data2.push_back(
00449                       B
00450                       +
00451                       s*(C-A)/n20*rho
00452                       +
00453                       s*s*(3*(C-B)-2*(C-A)/n20*rho-(D-B)/n31*rho)
00454                       +
00455                       s*s*s*((D-B)/n31*rho+(C-A)/n20*rho+2*(B-C))
00456                       );
00457 
00458 
00459     }
00460   data = data2;
00461 
00462 
00463   return 0;
00464 }
00465 
00466 
00467 int Curve_3D::load_curve(const char* filename)
00468 {
00469   
00470   #define SIZE_BUFFER 1024
00471   char buffer[SIZE_BUFFER]={'\0'};
00472 
00473 
00474 
00475   FILE *fid=NULL;
00476   fid=fopen(filename,"r");
00477   if(fid==NULL)
00478     {
00479       printf("ERROR opening file for loading %s\n",filename);
00480       exit(-1);
00481     }
00482 
00483 
00484   V_3D x;float x0=0.0,y0=0.0,z0=0.0;
00485   while(fscanf(fid,"%s",buffer)!=EOF)
00486     {
00487       switch(buffer[0])
00488         {
00489         case '#'://comments
00490           fgets(buffer,SIZE_BUFFER,fid);
00491           break;
00492         default:
00493           if(sscanf(buffer,"%f",&x0)!=1)
00494             {printf("Error reading curve file in %s [%s]\n",filename,buffer);exit(-1);}
00495           if(fscanf(fid,"%f",&y0)!=1 || fscanf(fid,"%f\n",&z0)!=1)
00496             {printf("Error reading curve file in %s at line [%s]\n",filename,buffer);exit(-1);}
00497           x.set(x0,y0,z0);
00498           add_point(x);
00499           break;
00500 
00501         }
00502     }
00503   
00504 
00505   
00506 
00507 
00508   if(fclose(fid)!=0)
00509     {printf("Closing file %s failed, error\n",filename);exit(-1);}
00510 
00511 
00512 
00513   return 0;
00514 }
00515 
00516 
00517 
00518 int Curve_3D::save_curve(const char* filename) const
00519 {
00520 
00521 
00522   FILE *fid=NULL;
00523   fid=fopen(filename,"w");
00524   if(fid==NULL)
00525     {
00526       printf("ERROR opening file for saving %s\n",filename);
00527       exit(-1);
00528     }
00529   
00530   fprintf(fid,"# Curve Model %s\n",filename);
00531   fprintf(fid,"# N_vertex=%d \n\n",size());
00532 
00533   V_3D X;
00534   int k_vertex=0,N_vertex=size();
00535   for(k_vertex=0;k_vertex<N_vertex;k_vertex++)
00536     {
00537       X=(*this)[k_vertex];
00538       fprintf(fid,"%f %f %f\n",X[0],X[1],X[2]);
00539     }
00540   
00541 
00542 
00543   if(fclose(fid)!=0)
00544     {printf("Closing file %s failed, error\n",filename);exit(-1);}
00545 
00546   return 0;
00547 }
00548 
00549 
00550 std::vector <V_3D>& Curve_3D::to_vector(){return data;}
00551 const std::vector <V_3D>& Curve_3D::to_vector() const{return data;}
00552 
00553 int Curve_3D::set(const std::vector <V_3D>& _curve)
00554 {
00555   destroy();
00556   for(int k=0;k<int(_curve.size());k++)
00557     add(_curve[k]);
00558   return 0;
00559 }
00560 int Curve_3D::set(const std::vector <double>& _curve)
00561 {
00562   destroy();
00563   if( (_curve.size()%3) != 0)
00564     {printf("Error in set in Curve_3D, the curve positions is not a multiple of 3\n");exit(-1);}
00565   for(int k=0;k<int(_curve.size())/3;k++)
00566     add(V_3D(_curve[3*k+0],_curve[3*k+1],_curve[3*k+2]));
00567   return 0;
00568 }
00569 
00570 bool operator==(const Curve_3D& curve_1, const Curve_3D& curve_2)
00571 {
00572   if(curve_1.size()!=curve_2.size())
00573     return 0;
00574   for(int k=0;k<curve_1.size();k++)
00575     if(curve_1[k]!=curve_2[k])
00576       return 0;
00577   return 1;
00578 }
00579 bool operator!=(const Curve_3D& curve_1, const Curve_3D& curve_2)
00580 {
00581   if(curve_1==curve_2)
00582     return 0;
00583   return 1;
00584 }

Generated on Mon Mar 30 16:55:54 2009 by  doxygen 1.5.6