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