00001
00002 #include "bsol_intrinsic_curve_2d.h"
00003
00004
00005 #include <vsol/vsol_point_2d.h>
00006 #include <vsol/vsol_polyline_2d.h>
00007 #include <vsol/vsol_digital_curve_2d.h>
00008 #include <vcl_cassert.h>
00009 #include <vcl_cmath.h>
00010 #include <vcl_fstream.h>
00011 #include <vnl/vnl_math.h>
00012
00013 #include <vcl_string.h>
00014
00015
00016
00017
00018
00019
00020
00021
00022 bsol_intrinsic_curve_2d::bsol_intrinsic_curve_2d()
00023 {
00024 storage_=new vcl_vector<vsol_point_2d_sptr>();
00025 isOpen_=true;
00026 }
00027
00028
00029
00030
00031
00032 bsol_intrinsic_curve_2d::bsol_intrinsic_curve_2d(const vcl_vector<vsol_point_2d_sptr> &new_vertices)
00033 {
00034 storage_=new vcl_vector<vsol_point_2d_sptr>(new_vertices);
00035 isOpen_=true;
00036 }
00037
00038
00039 bsol_intrinsic_curve_2d::bsol_intrinsic_curve_2d(const vsol_polyline_2d_sptr poly)
00040 {
00041 storage_ = new vcl_vector<vsol_point_2d_sptr>();
00042 for (unsigned i = 0; i < poly->size(); i++)
00043 storage_->push_back(poly->vertex(i));
00044 isOpen_=true;
00045 }
00046
00047
00048
00049
00050
00051 bsol_intrinsic_curve_2d::bsol_intrinsic_curve_2d(const bsol_intrinsic_curve_2d &other)
00052 : vsol_curve_2d(other)
00053 {
00054 storage_=new vcl_vector<vsol_point_2d_sptr>(*other.storage_);
00055 for (unsigned int i=0;i<storage_->size();++i)
00056 (*storage_)[i]=new vsol_point_2d(*((*other.storage_)[i]));
00057
00058 isOpen_ = other.isOpen_;
00059 }
00060
00061
00062
00063
00064 bsol_intrinsic_curve_2d::~bsol_intrinsic_curve_2d()
00065 {
00066 delete storage_;
00067 }
00068
00069
00070
00071
00072
00073 vsol_spatial_object_2d* bsol_intrinsic_curve_2d::clone(void) const
00074 {
00075 return new bsol_intrinsic_curve_2d(*this);
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085 bool bsol_intrinsic_curve_2d::operator==(const bsol_intrinsic_curve_2d &other) const
00086 {
00087 bool result = (this==&other);
00088
00089 if (!result)
00090 {
00091 result = (storage_->size()==other.storage_->size());
00092 if (result)
00093 {
00094 vsol_point_2d_sptr p=(*storage_)[0];
00095
00096 unsigned int i=0;
00097 for (result=false;i<storage_->size()&&!result;++i)
00098 result = (*p==*(*other.storage_)[i]);
00099 if (result)
00100 {
00101 for (int j=1;j<size()&&result;++i,++j)
00102 {
00103 if (i>=storage_->size()) i=0;
00104 result = ((*storage_)[i]==(*storage_)[j]);
00105 }
00106 }
00107 }
00108 }
00109 return result;
00110 }
00111
00112
00113
00114 bool bsol_intrinsic_curve_2d::operator==(const vsol_spatial_object_2d& obj) const
00115 {
00116 return obj.is_a() == "bsol_intrinsic_curve_2d" &&
00117 operator==(static_cast<bsol_intrinsic_curve_2d const&>(obj));
00118 }
00119
00120
00121
00122
00123 void bsol_intrinsic_curve_2d::clear(void)
00124 {
00125 s_.clear();
00126 arcLength_.clear();
00127 normArcLength_.clear();
00128 length_ = 0;
00129 curvature_.clear();
00130 angle_.clear();
00131 totalCurvature_ = 0;
00132 totalAngleChange_ = 0;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142 double bsol_intrinsic_curve_2d::curvature(const int i) const
00143 {
00144 assert(valid_index(i));
00145 return curvature_[i];
00146 }
00147
00148
00149
00150
00151 double bsol_intrinsic_curve_2d::angle(const int i) const
00152 {
00153 assert(valid_index(i));
00154 return angle_[i];
00155 }
00156
00157
00158
00159
00160 void bsol_intrinsic_curve_2d::compute_bounding_box(void) const
00161 {
00162 set_bounding_box((*storage_)[0]->x(), (*storage_)[0]->y());
00163 for (unsigned int i=1;i<storage_->size();++i)
00164 add_to_bounding_box((*storage_)[i]->x(), (*storage_)[i]->y());
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 void bsol_intrinsic_curve_2d::set_p0(const vsol_point_2d_sptr &new_p0)
00177 {
00178 p0_=new_p0;
00179 storage_->push_back(p0_);
00180 }
00181
00182
00183
00184
00185
00186 void bsol_intrinsic_curve_2d::set_p1(const vsol_point_2d_sptr &new_p1)
00187 {
00188 p1_=new_p1;
00189 storage_->push_back(p0_);
00190 }
00191
00192
00193
00194
00195 void bsol_intrinsic_curve_2d::add_vertex(const vsol_point_2d_sptr &new_p, bool bRecomputeProperties)
00196 {
00197 storage_->push_back(new_p);
00198 if (bRecomputeProperties) computeProperties();
00199 }
00200
00201
00202
00203
00204 void bsol_intrinsic_curve_2d::remove_vertex(const int i, bool bRecomputeProperties)
00205 {
00206 assert (valid_index(i));
00207 storage_->erase(storage_->begin() + i);
00208 if (bRecomputeProperties) computeProperties();
00209 }
00210
00211 void bsol_intrinsic_curve_2d::modify_vertex(const int i, double x, double y, bool bRecomputeProperties)
00212 {
00213 assert (valid_index(i));
00214 (*storage_)[i]->set_x(x);
00215 (*storage_)[i]->set_y(y);
00216 if (bRecomputeProperties) computeProperties();
00217 }
00218
00219
00220 void bsol_intrinsic_curve_2d::insert_vertex(const int i, double x, double y, bool bRecomputeProperties)
00221 {
00222 assert (valid_index(i));
00223 vsol_point_2d_sptr pt = new vsol_point_2d(x,y);
00224 vcl_vector<vsol_point_2d_sptr>::iterator it = storage_->begin();
00225 it += i;
00226 storage_->insert(it, pt);
00227 if (bRecomputeProperties) computeProperties();
00228 }
00229
00230 void bsol_intrinsic_curve_2d::readCONFromFile(vcl_string fileName)
00231 {
00232 double x, y;
00233 char buffer[2000];
00234 int nPoints;
00235
00236
00237 if (size() !=0)
00238 clear();
00239
00240
00241 vcl_ifstream fp(fileName.c_str(), vcl_ios::in);
00242 if (!fp) {
00243 vcl_cout<<" : Unable to Open "<<fileName<<vcl_endl;
00244 return;
00245 }
00246
00247
00248 fp.getline(buffer,2000);
00249
00250
00251
00252 vcl_string openFlag;
00253
00254 vcl_getline(fp, openFlag);
00255
00256 if (openFlag.find("OPEN",0) != vcl_string::npos)
00257 isOpen_ = true;
00258
00259 else if (openFlag.find("CLOSE",0) != vcl_string::npos)
00260 isOpen_ = false;
00261 else{
00262 vcl_cerr << "Invalid File " << fileName.c_str() << vcl_endl
00263 << "Should be OPEN/CLOSE " << openFlag << vcl_endl;
00264 return;
00265 }
00266
00267 fp >> nPoints;
00268 vcl_cout << "Number of Points from Contour: " << nPoints
00269 << "\nContour flag is "<< isOpen_ << " (1 for open, 0 for close)\n";
00270
00271 for (int i=0;i<nPoints;i++) {
00272 fp >> x >> y;
00273 add_vertex(x,y);
00274 }
00275
00276 fp.close();
00277 computeProperties();
00278 }
00279
00280
00281
00282 void bsol_intrinsic_curve_2d::computeArcLength()
00283 {
00284
00285 arcLength_.clear();
00286 s_.clear();
00287 length_=0;
00288 arcLength_.push_back(0.0);
00289 s_.push_back(0.0);
00290
00291 double px=(*storage_)[0]->x();
00292 double py=(*storage_)[0]->y();
00293 for (int i=1;i<size();i++)
00294 {
00295 double cx=(*storage_)[i]->x();
00296 double cy=(*storage_)[i]->y();
00297 double dL = vnl_math_hypot(cx-px,cy-py);
00298 length_ += dL;
00299 arcLength_.push_back(length_);
00300 s_.push_back(dL);
00301 px=cx;
00302 py=cy;
00303 }
00304
00305 assert (s_.size()==arcLength_.size());
00306
00307
00308
00309 #if 0 // commented out
00310
00311 if (!isOpen_)
00312 {
00313 px=(*storage_)[size()-1]->x();
00314 py=(*storage_)[size()-1]->y();
00315 double cx=(*storage_)[0]->x();
00316 double cy=(*storage_)[0]->y();
00317 double dL=vcl_sqrt(vcl_pow(cx-px,2)+vcl_pow(cy-py,2));
00318 length_ += dL;
00319 arcLength_[0]=length_;
00320 }
00321 #endif // 0
00322
00323
00324 normArcLength_.clear();
00325 for (int i=0;i<size();i++)
00326 normArcLength_.push_back(arcLength_[i]/length_);
00327
00328 #ifdef DEBUG
00329 vcl_cout << "Norm arc length values:\n";
00330 for (int i = 0; i<size(); i++)
00331 vcl_cout << "normArcLength_[" << i << "]: " << normArcLength_[i] << vcl_endl;
00332
00333 vcl_cout << "arc length values:\n";
00334 for (int i = 0; i<size(); i++)
00335 vcl_cout << "arcLength_[" << i << "]: " << arcLength_[i] << vcl_endl;
00336 #endif
00337 }
00338
00339
00340 void bsol_intrinsic_curve_2d::computeCurvatures()
00341 {
00342
00343 curvature_.clear();
00344 curvature_.push_back(0.0);
00345 totalCurvature_=0.0;
00346
00347 for (int i=1;i<size();i++)
00348 {
00349 double pdx=dx_[i-1];
00350 double pdy=dy_[i-1];
00351 double cdx=dx_[i];
00352 double cdy=dy_[i];
00353 double dL=arcLength_[i]-arcLength_[i-1];
00354 double d2x=0, d2y=0;
00355 if (dL > ZERO_TOLERANCE) {
00356 d2x=(cdx-pdx)/dL;
00357 d2y=(cdy-pdy)/dL;
00358 }
00359 double K = 0;
00360 if (vcl_fabs(cdx) >= ZERO_TOLERANCE || vcl_fabs(cdy) >= ZERO_TOLERANCE)
00361 K=(d2y*cdx-d2x*cdy)/vcl_pow((vcl_pow(cdx,2)+vcl_pow(cdy,2)),3/2);
00362 #ifdef DEBUG
00363 vcl_cout << d2x << ' ' << d2y << ' ' << dL << ' ' << cdx << ' ' << cdy << ' ' << K << vcl_endl;
00364 #endif
00365 curvature_.push_back(K);
00366 totalCurvature_+=K;
00367 }
00368
00369 #if 1 // commented out
00370
00371 if (!isOpen_)
00372 {
00373 double pdx=dx_[size()-1];
00374 double pdy=dy_[size()-1];
00375 double cdx=dx_[0];
00376 double cdy=dy_[0];
00377 double dL=arcLength_[0]-arcLength_[size()-1];
00378 double d2x, d2y;
00379 if (dL > ZERO_TOLERANCE ) {
00380 d2x=(cdx-pdx)/dL;
00381 d2y=(cdy-pdy)/dL;
00382 }
00383 else
00384 d2x=d2y=0;
00385 double K;
00386 if (vcl_fabs(cdx) < ZERO_TOLERANCE && vcl_fabs(cdy) < ZERO_TOLERANCE)
00387 K=0;
00388 else
00389 K=(d2y*cdx-d2x*cdy)/vcl_pow((vcl_pow(cdx,2)+vcl_pow(cdy,2)),3/2);
00390 curvature_[0]=K;
00391 }
00392 #endif // 0
00393 }
00394
00395
00396 void bsol_intrinsic_curve_2d::computeDerivatives()
00397 {
00398
00399 dx_.clear();
00400 dx_.push_back(0.0);
00401 dy_.clear();
00402 dy_.push_back(0.0);
00403
00404 double px=(*storage_)[0]->x();
00405 double py=(*storage_)[0]->y();
00406 for (int i=1;i<size();i++)
00407 {
00408 double cx=(*storage_)[i]->x();
00409 double cy=(*storage_)[i]->y();
00410 double dL=vcl_sqrt(vcl_pow(cx-px,2)+vcl_pow(cy-py,2));
00411 if (dL > ZERO_TOLERANCE) {
00412 dx_.push_back((cx-px)/dL);
00413 dy_.push_back((cy-py)/dL);
00414 }
00415 else{
00416 dx_.push_back(0.0);
00417 dy_.push_back(0.0);
00418 }
00419 px=cx;
00420 py=cy;
00421 }
00422
00423 #if 1 // commented out
00424
00425 if (!isOpen_)
00426 {
00427 double px=(*storage_)[size()-1]->x();
00428 double py=(*storage_)[size()-1]->y();
00429 double cx=(*storage_)[0]->x();
00430 double cy=(*storage_)[0]->y();
00431 double dL=vcl_sqrt(vcl_pow(cx-px,2)+vcl_pow(cy-py,2));
00432 dx_[0]=(cx-px)/dL;
00433 dy_[0]=(cy-py)/dL;
00434 }
00435 #endif // 0
00436 }
00437
00438
00439 void bsol_intrinsic_curve_2d::computeAngles()
00440 {
00441 angle_.clear();
00442 angle_.push_back(0.0);
00443 totalAngleChange_=0.0;
00444
00445 double px=(*storage_)[0]->x();
00446 double py=(*storage_)[0]->y();
00447 for (int i=1;i<size();i++)
00448 {
00449 double cx=(*storage_)[i]->x();
00450 double cy=(*storage_)[i]->y();
00451 double theta=vcl_atan2(cy-py,cx-px);
00452 angle_.push_back(theta);
00453 px=cx;
00454 py=cy;
00455 }
00456
00457 if (size()>2) {
00458 angle_[0]=angle_[1];
00459 for (unsigned int i=1;i<angle_.size();i++) {
00460 #ifdef DEBUG
00461 vcl_cout << angle_[i] << ' ' << angle_[i-1] << vcl_endl;
00462 #endif
00463 totalAngleChange_ += vcl_fabs(angle_[i]-angle_[i-1]);
00464 }
00465 }
00466
00467
00468
00469
00470
00471
00472
00473 #if 1
00474
00475 if (!isOpen_)
00476 {
00477 double px=(*storage_)[size()-1]->x();
00478 double py=(*storage_)[size()-1]->y();
00479 double cx=(*storage_)[0]->x();
00480 double cy=(*storage_)[0]->y();
00481 double theta=vcl_atan2(cy-py,cx-px);
00482 angle_[0]=theta;
00483
00484 #if 0 // commented out
00485
00486 if (vcl_sqrt((cx-px)*(cx-px)+(cy-py)*(cy-py))<2)
00487 c->angle[0]=vcl_atan2(cy-py,cx-px);
00488 #endif // 0
00489 }
00490 #endif
00491 }
00492
00493
00494 void bsol_intrinsic_curve_2d::computeProperties()
00495 {
00496 if (size() ==0)
00497 return;
00498
00499 computeArcLength();
00500 computeDerivatives();
00501 computeCurvatures();
00502 computeAngles();
00503 }
00504
00505
00506 bool bsol_intrinsic_curve_2d::upsample(int new_size)
00507 {
00508 if (size() >= new_size) {
00509 vcl_cout << "In bsol_intrinsic_curve_2d::upsample method: Curve size is larger than or equal to new_size already, exiting!\n";
00510 return true;
00511 }
00512
00513 vsol_digital_curve_2d_sptr dc = new vsol_digital_curve_2d(*storage_);
00514
00515
00516 if (!isOpen()) {
00517 dc->add_vertex((*storage_)[0]);
00518 }
00519
00520 clear();
00521 storage_->clear();
00522
00523 double T = dc->length()/new_size;
00524 vcl_cout << "T value for new_size is: " << T << vcl_endl;
00525
00526 for (unsigned int i=1; i<dc->size(); ++i)
00527 {
00528 double len = ((dc->point(i))->get_p()-(dc->point(i-1))->get_p()).length();
00529
00530 storage_->push_back(dc->point(i-1));
00531
00532 int j = 0;
00533 while (len - j*T >= (T+(T/2))) {
00534 vcl_cout << "i: " << i << " interpolating " << (i-1)+(j+1)*T/len << vcl_endl;
00535 storage_->push_back(new vsol_point_2d(dc->interp((i-1)+(j+1)*T/len)));
00536 j++;
00537 }
00538 }
00539
00540 vcl_cout << "after upsampling bsol curve size: " << size() << " (should be " << new_size << ")\n";
00541 return true;
00542 }
00543
00544 #if 0 // rest of file commented out
00545
00546
00547 bsol_intrinsic_curve_2d::bsol_intrinsic_curve_2d()
00548 {
00549 vcl_vector< vsol_point_2d > a;
00550 vcl_vector<double> b;
00551
00552 (*storage_)=a;
00553 s_ = b;
00554 arcLength_ = b;
00555 normArcLength_ = b;
00556 dx_ = b;
00557 dy_ = b;
00558 curvature_ = b;
00559 angle_ = b;
00560 size()=0;
00561 length_=0.0;
00562 totalCurvature_=0.0;
00563 totalAngleChange_=0.0;
00564 isOpen_=true;
00565 };
00566
00567
00568 bsol_intrinsic_curve_2d::bsol_intrinsic_curve_2d(vsol_point_2d *pt, int size, bool isOpen)
00569 {
00570 size()=size;
00571 isOpen_=isOpen;
00572 for (int i=0;i<size;i++) {
00573 (*storage_).push_back(pt[i]);
00574 }
00575 computeProperties();
00576 }
00577
00578
00579 bsol_intrinsic_curve_2d::bsol_intrinsic_curve_2d(double *x, double *y, int size, bool isOpen)
00580 {
00581 size()=size;
00582 isOpen_=isOpen;
00583 for (int i=0;i<size;i++) {
00584 vsol_point_2d pt(x[i],y[i]);
00585 (*storage_).push_back(pt);
00586 }
00587 computeProperties();
00588 }
00589
00590
00591 bsol_intrinsic_curve_2d::bsol_intrinsic_curve_2d(const bsol_intrinsic_curve_2d &rhs)
00592 {
00593 if (this != &rhs)
00594 {
00595 (*storage_) = rhs.(*storage_);
00596 s_ = rhs.s_;
00597 arcLength_ = rhs.arcLength_;
00598 normArcLength_ = rhs.normArcLength_;
00599 dx_ = rhs.dx_;
00600 dy_ = rhs.dy_;
00601 curvature_ = rhs.curvature_;
00602 angle_ = rhs.angle_;
00603
00604 size()=rhs.size();
00605 isOpen_=rhs.isOpen_;
00606 totalCurvature_= rhs.totalCurvature_;
00607 totalAngleChange_=rhs.totalAngleChange_;
00608 length_=rhs.length_;
00609 }
00610 }
00611
00612
00613 bsol_intrinsic_curve_2d& bsol_intrinsic_curve_2d::operator=(const bsol_intrinsic_curve_2d &rhs)
00614 {
00615 if (this != &rhs) {
00616 (*storage_) = rhs.(*storage_);
00617 s_ = rhs.s_;
00618 arcLength_ = rhs.arcLength_;
00619 normArcLength_ = rhs.normArcLength_;
00620 dx_ = rhs.dx_;
00621 dy_ = rhs.dy_;
00622 curvature_ = rhs.curvature_;
00623 angle_ = rhs.angle_;
00624
00625 size() = rhs.size();
00626 isOpen_ = rhs.isOpen_;
00627 length_ = rhs.length_;
00628 totalCurvature_ = rhs.totalCurvature_;
00629 totalAngleChange_ = rhs.totalAngleChange_;
00630
00631 computeProperties();
00632 }
00633 return *this;
00634 }
00635
00636
00637 template <class double,class double>
00638 void bsol_intrinsic_curve_2d<double,double>::readDataFromFile(vcl_string fileName)
00639 {
00640 }
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651 void bsol_intrinsic_curve_2d::readDataFromFile(vcl_string fileName)
00652 {
00653
00654 if (size() !=0)
00655 clear();
00656
00657 vcl_ifstream infp(fileName.c_str(), vcl_ios::in);
00658
00659 if (!infp) {
00660 vcl_cout << " Error opening file " << fileName << vcl_endl;
00661 vcl_exit(1);
00662 }
00663
00664 char lineBuffer[2000];
00665 infp.getline(lineBuffer,2000);
00666 if (vcl_strncmp(lineBuffer,"CONTOUR",7)) {
00667 vcl_cerr << "Invalid File " << fileName.c_str() << vcl_endl
00668 << "Should be CONTOUR " << lineBuffer << vcl_endl;
00669 vcl_exit(1);
00670 }
00671
00672 char openFlag[2000];
00673 infp.getline(openFlag,2000);
00674 if (!vcl_strncmp(openFlag,"OPEN",4))
00675 isOpen_ = true;
00676 else if (!vcl_strncmp(openFlag,"CLOSE",5))
00677 isOpen_ = false;
00678 else{
00679 vcl_cerr << "Invalid File " << fileName.c_str() << vcl_endl
00680 << "Should be OPEN/CLOSE " << openFlag << vcl_endl;
00681 vcl_exit(1);
00682 }
00683
00684 int i,numOfPoints;
00685 infp >> numOfPoints;
00686
00687 double x,y;
00688 for (i=0;i<numOfPoints;i++) {
00689 infp >> x >> y;
00690 add_vertex(x,y);
00691 }
00692
00693 infp.close();
00694 computeProperties();
00695 }
00696
00697 void bsol_intrinsic_curve_2d::readDataFromVector(vcl_vector<vcl_pair<double,double> > v)
00698 {
00699 unsigned int numOfPoints=v.size();
00700
00701 double x,y;
00702 for (unsigned int i=0;i<numOfPoints;i++) {
00703 x=v[i].first;
00704 y=v[i].second;
00705
00706 add_vertex(x,y);
00707 }
00708
00709 computeProperties();
00710 }
00711
00712 #endif // 0