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
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
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
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
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
00154 data = data2;
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
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
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);
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
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
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 '#':
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 }