Go to the documentation of this file.00001
00002 #include "vsol_digital_curve_2d.h"
00003
00004
00005 #include <vsol/vsol_point_2d.h>
00006 #include <vcl_iostream.h>
00007 #include <vgl/vgl_point_2d.h>
00008 #include <vgl/vgl_closest_point.h>
00009 #include <vsl/vsl_vector_io.h>
00010 #include <vcl_cmath.h>
00011 #include <vcl_cassert.h>
00012
00013
00014
00015
00016
00017
00018
00019
00020 vsol_digital_curve_2d::vsol_digital_curve_2d()
00021 : vsol_curve_2d(), samples_()
00022 {
00023 }
00024
00025
00026
00027
00028
00029 vsol_digital_curve_2d::vsol_digital_curve_2d(const vcl_vector<vsol_point_2d_sptr> &samples)
00030 : vsol_curve_2d(), samples_(samples)
00031 {
00032 }
00033
00034
00035
00036
00037 vsol_digital_curve_2d::vsol_digital_curve_2d(const vsol_digital_curve_2d &other)
00038 : vsol_curve_2d(other), samples_()
00039 {
00040 for ( vcl_vector<vsol_point_2d_sptr>::const_iterator itr=other.samples_.begin();
00041 itr != other.samples_.end(); ++itr )
00042 this->samples_.push_back(new vsol_point_2d(**itr));
00043 }
00044
00045
00046
00047
00048 vsol_digital_curve_2d::~vsol_digital_curve_2d()
00049 {
00050 }
00051
00052
00053
00054
00055
00056 vsol_spatial_object_2d* vsol_digital_curve_2d::clone(void) const
00057 {
00058 return new vsol_digital_curve_2d(*this);
00059 }
00060
00061
00062
00063
00064
00065
00066
00067
00068 vsol_point_2d_sptr vsol_digital_curve_2d::p0(void) const
00069 {
00070 if ( samples_.empty() )
00071 return NULL;
00072
00073 return samples_.front();
00074 }
00075
00076
00077
00078
00079 vsol_point_2d_sptr vsol_digital_curve_2d::p1(void) const
00080 {
00081 if ( samples_.empty() )
00082 return NULL;
00083
00084 return samples_.back();
00085 }
00086
00087
00088
00089
00090
00091 vsol_point_2d_sptr vsol_digital_curve_2d::point(const int i) const
00092 {
00093
00094 assert(valid_index(i));
00095
00096 return samples_[i];
00097 }
00098
00099
00100
00101
00102
00103 vgl_point_2d<double>
00104 vsol_digital_curve_2d::interp(double index) const
00105 {
00106 assert(index >= 0.0);
00107 assert(index <= double(samples_.size()-1));
00108
00109 int i1 = (int)vcl_floor(index);
00110 if ( vcl_floor(index) == index )
00111 return samples_[i1]->get_p();
00112
00113 int i2 = (int)vcl_ceil(index);
00114 double f = index - vcl_floor(index);
00115
00116 vgl_point_2d<double> p1 = samples_[i1]->get_p();
00117 vgl_point_2d<double> p2 = samples_[i2]->get_p();
00118 return p1 + f*(p2-p1);
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 bool vsol_digital_curve_2d::operator==(const vsol_digital_curve_2d &other) const
00130 {
00131 if (this==&other)
00132 return true;
00133
00134
00135 bool epts_eq = vsol_curve_2d::endpoints_equal(other);
00136 if (!epts_eq)
00137 return false;
00138
00139 if (samples_.size()!=other.samples_.size())
00140 return false;
00141
00142 int n = samples_.size();
00143 for (int i=0; i<n; i++)
00144 if (*(samples_[i])!=*(other.samples_[i]))
00145 return false;
00146 return true;
00147 }
00148
00149
00150
00151 bool vsol_digital_curve_2d::operator==(const vsol_spatial_object_2d& obj) const
00152 {
00153 return
00154 obj.cast_to_curve() && obj.cast_to_curve()->cast_to_digital_curve() &&
00155 *this == *obj.cast_to_curve()->cast_to_digital_curve();
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 double vsol_digital_curve_2d::length(void) const
00167 {
00168 double curve_length = 0.0;
00169 for ( vcl_vector<vsol_point_2d_sptr>::const_iterator itr=samples_.begin();
00170 itr+1 != samples_.end(); ++itr )
00171 {
00172 curve_length += ((*(itr+1))->get_p() - (*itr)->get_p()).length();
00173 }
00174 return curve_length;
00175 }
00176
00177
00178
00179
00180
00181 void vsol_digital_curve_2d::compute_bounding_box(void) const
00182 {
00183
00184 set_bounding_box(samples_[0]->x(), samples_[0]->y());
00185 for (unsigned int i=1; i<samples_.size(); ++i)
00186 add_to_bounding_box(samples_[i]->x(), samples_[i]->y());
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 void vsol_digital_curve_2d::set_p0(const vsol_point_2d_sptr &new_p0)
00198 {
00199 samples_.front() = new_p0;
00200 }
00201
00202
00203
00204
00205
00206 void vsol_digital_curve_2d::set_p1(const vsol_point_2d_sptr &new_p1)
00207 {
00208 samples_.back() = new_p1;
00209 }
00210
00211
00212
00213
00214 void vsol_digital_curve_2d::add_vertex(const vsol_point_2d_sptr &new_p)
00215 {
00216 samples_.push_back(new_p);
00217 }
00218
00219
00220
00221
00222
00223
00224 void vsol_digital_curve_2d::b_write(vsl_b_ostream &os) const
00225 {
00226 vsl_b_write(os, version());
00227 vsl_b_write(os, samples_);
00228 }
00229
00230
00231
00232 void vsol_digital_curve_2d::b_read(vsl_b_istream &is)
00233 {
00234 if (!is)
00235 return;
00236
00237 short ver;
00238 vsl_b_read(is, ver);
00239 switch (ver)
00240 {
00241 default:
00242 assert(!"vsol_digital_curve_2d I/O version should be 1");
00243 case 1:
00244 vsl_b_read(is, samples_);
00245 }
00246 }
00247
00248
00249
00250 short vsol_digital_curve_2d::version() const
00251 {
00252 return 1;
00253 }
00254
00255
00256 void vsol_digital_curve_2d::print_summary(vcl_ostream &os) const
00257 {
00258 os << *this;
00259 }
00260
00261
00262
00263
00264
00265
00266
00267
00268 void
00269 vsl_b_write(vsl_b_ostream &os, const vsol_digital_curve_2d* p)
00270 {
00271 if (p==0) {
00272 vsl_b_write(os, false);
00273 }
00274 else {
00275 vsl_b_write(os,true);
00276 p->b_write(os);
00277 }
00278 }
00279
00280
00281
00282 void
00283 vsl_b_read(vsl_b_istream &is, vsol_digital_curve_2d* &p)
00284 {
00285 delete p;
00286 bool not_null_ptr;
00287 vsl_b_read(is, not_null_ptr);
00288 if (not_null_ptr) {
00289 p = new vsol_digital_curve_2d();
00290 p->b_read(is);
00291 }
00292 else
00293 p = 0;
00294 }
00295
00296 void vsol_digital_curve_2d::describe(vcl_ostream &strm, int blanking) const
00297 {
00298 if (blanking < 0) blanking = 0; while (blanking--) strm << ' ';
00299 strm << "[vsol_digital_curve_2d";
00300 for (unsigned int i=0; i<size(); ++i)
00301 strm << ' ' << *(point(i));
00302 strm << ']' << vcl_endl;
00303 }
00304
00305
00306
00307 double closest_index(const vgl_point_2d<double>& pt,
00308 const vsol_digital_curve_2d_sptr& curve)
00309 {
00310 const unsigned int n = curve->size();
00311 double *px = new double[n], *py = new double[n];
00312 for (unsigned int i=0; i<n; ++i)
00313 px[i]=curve->point(i)->x(), py[i]=curve->point(i)->y();
00314 double x, y;
00315 int index=vgl_closest_point_to_non_closed_polygon(x,y,px,py,n,pt.x(),pt.y());
00316 double dx = px[index+1]-px[index], dy = py[index+1]-py[index];
00317 double f = dx==0 ? (dy==0 ? 0.5 : (y-py[index])/dy) : (x-px[index])/dx;
00318 delete [] px; delete[] py;
00319 return f + index;
00320 }
00321
00322
00323
00324 bool split(const vsol_digital_curve_2d_sptr &input,
00325 double index,
00326 vsol_digital_curve_2d_sptr &output1,
00327 vsol_digital_curve_2d_sptr &output2)
00328 {
00329 const int n = input->size();
00330 if (index <= 0.0 || index >= double(n-1))
00331 return false;
00332
00333 vcl_vector<vsol_point_2d_sptr> vec1, vec2;
00334 vgl_point_2d<double> break_point = input->interp(index);
00335 vec2.push_back(new vsol_point_2d(break_point));
00336 for (int i=0; i<n; ++i) {
00337 if ( double(i) < index )
00338 vec1.push_back(input->point(i));
00339 if ( double(i) > index )
00340 vec2.push_back(input->point(i));
00341
00342 }
00343 vec1.push_back(new vsol_point_2d(break_point));
00344
00345 output1 = new vsol_digital_curve_2d(vec1);
00346 output2 = new vsol_digital_curve_2d(vec2);
00347 return true;
00348 }