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