Go to the documentation of this file.00001
00002 #include "vsol_polygon_3d.h"
00003
00004
00005 #include <vcl_cassert.h>
00006 #include <vcl_iostream.h>
00007 #include <vcl_cmath.h>
00008 #include <vsl/vsl_vector_io.h>
00009 #include <vsol/vsol_point_3d.h>
00010 #include <vgl/vgl_vector_3d.h>
00011 #include <vgl/vgl_homg_point_3d.h>
00012 #include <vgl/algo/vgl_fit_plane_3d.h>
00013
00014
00015
00016
00017 void vsol_polygon_3d::compute_plane()
00018 {
00019 vcl_vector<vgl_homg_point_3d<double> > pts;
00020 for (vcl_vector<vsol_point_3d_sptr>::iterator pit = storage_->begin();
00021 pit != storage_->end(); ++pit)
00022 pts.push_back(vgl_homg_point_3d<double>((*pit)->x(),(*pit)->y(),(*pit)->z(),1.0));
00023 vgl_fit_plane_3d<double> fp(pts);
00024 fp.fit(0.1, &vcl_cerr);
00025 plane_ = fp.get_plane();
00026 plane_.normalize();
00027 }
00028
00029
00030
00031
00032 vsol_polygon_3d::vsol_polygon_3d()
00033 : storage_(0)
00034 {
00035 }
00036
00037
00038
00039
00040
00041 vsol_polygon_3d::vsol_polygon_3d(vcl_vector<vsol_point_3d_sptr> const& new_vertices)
00042 {
00043
00044 assert(new_vertices.size()>=3);
00045 assert(valid_vertices(new_vertices));
00046
00047 storage_=new vcl_vector<vsol_point_3d_sptr>(new_vertices);
00048 this->compute_plane();
00049 }
00050
00051
00052
00053
00054 vsol_polygon_3d::vsol_polygon_3d(vsol_polygon_3d const& other)
00055 : vsol_region_3d(other)
00056 {
00057
00058
00059 storage_=new vcl_vector<vsol_point_3d_sptr>(*other.storage_);
00060 for (unsigned int i=0;i<storage_->size();++i)
00061 (*storage_)[i]=new vsol_point_3d(*((*other.storage_)[i]));
00062 plane_ = other.plane_;
00063 }
00064
00065
00066
00067
00068 vsol_polygon_3d::~vsol_polygon_3d()
00069 {
00070 delete storage_;
00071 }
00072
00073
00074
00075
00076
00077 vsol_spatial_object_3d* vsol_polygon_3d::clone(void) const
00078 {
00079 return new vsol_polygon_3d(*this);
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 vsol_point_3d_sptr vsol_polygon_3d::vertex(const int i) const
00091 {
00092
00093 assert(valid_index(i));
00094
00095 return (*storage_)[i];
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105 bool vsol_polygon_3d::operator==(vsol_polygon_3d const& other) const
00106 {
00107 bool result = (this==&other);
00108
00109 if (!result)
00110 {
00111 result = (storage_->size()==other.storage_->size());
00112
00113 if (result)
00114 {
00115 vsol_point_3d_sptr p=(*storage_)[0];
00116
00117 unsigned int i=0;
00118 for (result=false;i<storage_->size()&&!result;++i)
00119 result = (*p==*(*other.storage_)[i]);
00120 if (result)
00121 {
00122 for (unsigned int j=1;j<size()&&result;++i,++j)
00123 {
00124 if (i>=storage_->size()) i=0;
00125 result = ((*storage_)[i]==(*storage_)[j]);
00126 }
00127 }
00128 }
00129 }
00130 return result;
00131 }
00132
00133
00134
00135
00136 bool vsol_polygon_3d::operator==(vsol_spatial_object_3d const& obj) const
00137 {
00138 return
00139 obj.cast_to_region() && obj.cast_to_region()->cast_to_polygon() &&
00140 *this == *obj.cast_to_region()->cast_to_polygon();
00141 }
00142
00143
00144
00145
00146 void vsol_polygon_3d::compute_bounding_box(void) const
00147 {
00148 set_bounding_box((*storage_)[0]->x(),
00149 (*storage_)[0]->y(),
00150 (*storage_)[0]->z());
00151 for (unsigned int i=1;i<storage_->size();++i)
00152 add_to_bounding_box((*storage_)[i]->x(),
00153 (*storage_)[i]->y(),
00154 (*storage_)[i]->z());
00155 }
00156
00157
00158
00159
00160 double vsol_polygon_3d::area(void) const
00161 {
00162
00163 vcl_cerr << "Warning: vsol_polygon_3d::area() has not been implemented yet\n";
00164 return -1;
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 bool vsol_polygon_3d::is_convex(void) const
00177 {
00178 if (storage_->size()==3) return true;
00179
00180
00181
00182
00183
00184
00185
00186
00187 vgl_vector_3d<double> n = vgl_vector_3d<double>(0.0,0.0,0.0);
00188 for (unsigned int i=0; i<storage_->size(); ++i)
00189 {
00190 int j = (i>1) ? i-2 : i-2+storage_->size();
00191 int k = (i>0) ? i-1 : i-1+storage_->size();
00192 vsol_point_3d_sptr p0=(*storage_)[k];
00193 vsol_point_3d_sptr p1=(*storage_)[j];
00194 vsol_point_3d_sptr p2=(*storage_)[i];
00195 vgl_vector_3d<double> v1=p0->to_vector(*p1);
00196 vgl_vector_3d<double> v2=p1->to_vector(*p2);
00197 n = cross_product(v1,v2);
00198 if (n != vgl_vector_3d<double>(0.0,0.0,0.0))
00199 break;
00200 }
00201 if (n == vgl_vector_3d<double>(0.0,0.0,0.0))
00202 return true;
00203
00204 for (unsigned int i=0; i<storage_->size(); ++i)
00205 {
00206 int j = (i>1) ? i-2 : i-2+storage_->size();
00207 int k = (i>0) ? i-1 : i-1+storage_->size();
00208 vsol_point_3d_sptr p0=(*storage_)[k];
00209 vsol_point_3d_sptr p1=(*storage_)[j];
00210 vsol_point_3d_sptr p2=(*storage_)[i];
00211 vgl_vector_3d<double> v1=p0->to_vector(*p1);
00212 vgl_vector_3d<double> v2=p1->to_vector(*p2);
00213 vgl_vector_3d<double> n2 = cross_product(v1,v2);
00214 if (dot_product(n2,n) < 0)
00215 return false;
00216 if (!parallel(n2,n,1e-6))
00217 return false;
00218 }
00219 return true;
00220 }
00221
00222
00223
00224
00225
00226 bool vsol_polygon_3d::valid_vertices(const vcl_vector<vsol_point_3d_sptr> new_vertices) const
00227 {
00228 double tol = 1e-06;
00229 if (new_vertices.size() <= 3) return true;
00230
00231 vsol_point_3d_sptr p0=new_vertices[0];
00232 vsol_point_3d_sptr p1=new_vertices[1];
00233 vsol_point_3d_sptr p2=new_vertices[2];
00234
00235 vgl_vector_3d<double> v1 (p1->x()-p0->x(),
00236 p1->y()-p0->y(),
00237 p1->z()-p0->z());
00238
00239 vgl_vector_3d<double> v2 (p2->x()-p0->x(),
00240 p2->y()-p0->y(),
00241 p2->z()-p0->z());
00242 vgl_vector_3d<double> n = normalized(cross_product(v1,v2));
00243
00244 for (unsigned int i=3;i<new_vertices.size();++i)
00245 {
00246 p2=new_vertices[i];
00247 v2=vgl_vector_3d<double>(p2->x()-p0->x(),
00248 p2->y()-p0->y(),
00249 p2->z()-p0->z());
00250 #if 0
00251 if (dot_product(n,v2)!=0)
00252 return false;
00253 #endif
00254 double dp = vcl_fabs(dot_product(n,v2));
00255 if (dp>tol)
00256 return false;
00257 }
00258
00259 return true;
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 bool vsol_polygon_3d::in(vsol_point_3d_sptr const& ) const
00271 {
00272 vcl_cerr << "Warning: vsol_polygon_3d::in() has not been implemented yet\n";
00273 return false;
00274 }
00275
00276
00277
00278
00279 vgl_vector_3d<double>
00280 vsol_polygon_3d::normal_at_point(vsol_point_3d_sptr const& ) const
00281 {
00282 return plane_.normal();
00283 }
00284
00285
00286
00287 vgl_vector_3d<double> vsol_polygon_3d::normal() const
00288 {
00289 return plane_.normal();
00290 }
00291
00292
00293
00294
00295
00296
00297 inline void vsol_polygon_3d::describe(vcl_ostream &strm, int blanking) const
00298 {
00299 if (blanking < 0) blanking = 0; while (blanking--) strm << ' ';
00300 if (size() == 0)
00301 strm << "[vsol_polygon_3d null]";
00302 else {
00303 strm << "[vsol_polygon_3d Nverts=" << size()
00304 << " Area=" << area();
00305 for (unsigned int i=0; i<size(); ++i)
00306 strm << " p" << i << ':' << *(vertex(i));
00307 strm << ']';
00308 }
00309 strm << vcl_endl;
00310 }
00311
00312
00313
00314
00315
00316
00317 void vsol_polygon_3d::b_write(vsl_b_ostream &os) const
00318 {
00319 vsl_b_write(os, version());
00320 vsol_spatial_object_3d::b_write(os);
00321 if (!storage_)
00322 vsl_b_write(os, false);
00323 else
00324 {
00325 vsl_b_write(os, true);
00326 vsl_b_write(os, *storage_);
00327 }
00328 }
00329
00330
00331 void vsol_polygon_3d::b_read(vsl_b_istream &is)
00332 {
00333 short ver;
00334 vsl_b_read(is, ver);
00335 switch (ver)
00336 {
00337 case 1:
00338 vsol_spatial_object_3d::b_read(is);
00339
00340 delete storage_;
00341 storage_ = new vcl_vector<vsol_point_3d_sptr>();
00342 bool valid_ptr;
00343 vsl_b_read(is, valid_ptr);
00344 if (!valid_ptr)
00345 return;
00346 vsl_b_read(is, *storage_);
00347 this->compute_plane();
00348 break;
00349 default:
00350 vcl_cerr << "vsol_polygon_3d: unknown I/O version " << ver << '\n';
00351 }
00352 }
00353
00354
00355 short vsol_polygon_3d::version() const
00356 {
00357 return 1;
00358 }
00359
00360
00361 void vsol_polygon_3d::print_summary(vcl_ostream &os) const
00362 {
00363 os << *this;
00364 }
00365
00366
00367 void
00368 vsl_b_write(vsl_b_ostream &os, vsol_polygon_3d const* p)
00369 {
00370 if (p==0) {
00371 vsl_b_write(os, false);
00372 }
00373 else{
00374 vsl_b_write(os,true);
00375 p->b_write(os);
00376 }
00377 }
00378
00379
00380 void
00381 vsl_b_read(vsl_b_istream &is, vsol_polygon_3d* &p)
00382 {
00383 delete p;
00384 bool not_null_ptr;
00385 vsl_b_read(is, not_null_ptr);
00386 if (not_null_ptr) {
00387
00388 p = new vsol_polygon_3d();
00389 p->b_read(is);
00390 }
00391 else
00392 p = 0;
00393 }